Setting URI User part in "Contact" field of INVITE reply


I am trying to set my Asterisk server to receive inbound calls from the trunk, but it is being harder than I thought.

At the moment, outbound calls seem to be fine, but when receiving calls, I answer the call in the extension but it doesn’t seem to establish connection. In the outside phone, it just waits some seconds and appears a “Failed to estabilish the call” message. Not even ringing tones.

I am checking tcpdump from a known working device for a trunk (my ISP’s router), and the only difference I see is that in the response to the INVITE request, the username is attached to the host in the “Contact URI”, which doesn’t happen when trying with Asterisk. Please check the screenshoot below (consider that the port is mapped in the router, so you are seeing the packets both inside and outside the NAT).

After that, no RTP packets are received from the trunk, even though Asterisk sends them. I think it is because of that, since the trunk tries to send many INVITEs (it thinks it hasn’t got any response).

I’m hosting Asterisk in a Docker container (host network, so having the same network as the device itself) in a RPI connected to my router, that does NAT.

Router has port 5060 and 10000-10010 to the RPI (so directly to the Asterisk container).

My pjsip.conf is:

type = transport
protocol = udp
bind =
local_net =
external_media_address =
external_signaling_address =

type = registration
retry_interval = 20
max_retries = 10
contact_user = +349<…>
expiration = 120
transport = transport-udp
outbound_auth = trunk
client_uri = sip:+349<…>
server_uri =
outbound_proxy = sip:;lr;hide

type = auth
password =
username = 349<…>

type = identify
endpoint = trunk
match =

type = aor
max_contacts = 10
contact = sip:+349<…>
outbound_proxy = sip:;lr;hide
qualify_frequency = 30

type = endpoint
context = from-trunk
dtmf_mode = none
disallow = all
allow = alaw
rtp_symmetric = yes
rewrite_contact = yes
direct_media = no
from_domain =
from_user = +349<…>
contact_user = +349<…>
aors = trunk
outbound_auth = trunk
outbound_proxy = sip:;lr;hide


password=<password for extension 101>


exten => +349<…>,1,Dial(PJSIP/101)


Do you have some idea about how solving my issue?

Thank you!

The provider is broken if the user part of the contact URI makes any difference to them. Whilst I’ve heard of this brain damage on INVITEs it is less likely on OKs. The only purpose of the contact address is to responses back to the system that sent them. The value of the contact user should not make any difference to that within the peer system.

In any case, I can’t really tell what is going in with a splodged out wireshark listing. Please provide pjsip set logger on output, with redacted information annotated in a way which makes it clear what it represents, and whether it is in a local, shared, or public IP address range.

You appear to be behind NAT, but you have specified empty public addresses. It’s not clear whether that is real, or a poorly done redaction.

Note that the SIP specification does not use the terms trunk or extension and doesn’t use server in the sense that you are using it.

Sorry about the IP. In “external_media_address” and “external_signaling_address” there is, indeed, my public IP. Also in the auth object of the trunk, there’s the authentication password.

In <--- Transmitting SIP request (449 bytes) to UDP: --->OPTI - the verbose pjsip log can be seen (it seems it’s too long to paste it here). is the trunk IP.

Thank you a lot!

I was under the impression that chan_pjsip used a placeholder user part. If so, I’m wondering if you are using the approved version of PJSIP. As hinted above, the user part is not needed for the way that PJSIP works, so it is conceivable the the upstream removed it, meaning there is no user part to substitute with a custom value.

As noted above your provider should not be reading anything into the user part or whether or not it exists, but, unfortunately, some seem to use it for the account name.