PJSIP Incoming/Internal Calls Drop After Exactly 30-32 Seconds Behind NAT (MikroTik)

Subject: PJSIP Incoming/Internal Calls Drop After Exactly 30-32 Seconds Behind NAT (MikroTik)

Hello everyone,

I have been struggling with a very frustrating issue for weeks and I hope someone here can help me.

Environment:

  • PBX Platform: Issabel 4.1 (Asterisk 16+ with chan_pjsip)
  • Network: Issabel server is behind a MikroTik router (NAT)
  • Clients: All internal extensions are PJSIP type (softphones, mostly Linphone and Grandstream GXP1625)
  • Public IP: ... (static)
  • Internal IP of Issabel: 192.168.2.99

The Problem:

  1. When two internal extensions call each other, the call is established successfully.
  2. Audio works fine for about 30–32 seconds.
  3. After exactly 30–32 seconds, the call drops automatically.
  4. Asterisk sends a BYE message, and the call ends.
  5. The issue occurs regardless of whether the caller is behind the same NAT or a remote NAT.

What I Have Observed:

  • The ACK message is not being sent properly from the endpoint after the 200 OK response.
  • Asterisk waits for the ACK and then sends BYE after ~30 seconds due to session timers or rtp_timeout.
  • In my MikroTik firewall connections, I can see a direct UDP connection from the Issabel public IP to the internal IP of the client (e.g., 192.168.x.x) during the call. This indicates that direct_media is still active despite my settings.
  • SIP OPTIONS (qualify) are being exchanged successfully (200 OK responses are received).
  • The issue only occurs during active calls; registration and presence work fine.

<— Transmitting SIP response (794 bytes) to UDP:2.180.152.223:47105 —>
SIP/2.0 200 OK

<— Transmitting SIP request (357 bytes) to UDP:2.180.152.223:47105 —>
BYE sip:107@2.180.152.223:47105 SIP/2.0

– Channel PJSIP/107-00000001 left ‘simple_bridge’ basic-bridge
== Spawn extension (from-internal, 2020, 8) exited non-zero on ‘PJSIP/107-00000001’

pjsip show endpoint 107

Endpoint: <Endpoint/CID…> <State…> <Channels.>

I/OAuth: <AuthId/UserName…>
Aor: <Aor…>
Contact: <Aor/ContactUri…> <Hash…> <RTT(ms)..>
Transport: <TransportId…> <BindAddress…>
Identify: <Identify/Endpoint…>
Match: <criteria…>
Channel: <ChannelId…> <State…> <Time…>
Exten: <DialedExten…> CLCID: <ConnectedLineCID…>

Endpoint: 107/107 Unavailable 0 of inf
InAuth: auth107/107
Aor: 107 1
Transport: transport-udp udp 0 0 0.0.0.0:5060

ParameterName : ParameterValue

100rel : yes
accept_multiple_sdp_answers : false
accountcode :
acl : deny/permit
aggregate_mwi : true
allow : (gsm|ulaw|alaw)
allow_overlap : true
allow_subscribe : true
allow_transfer : true
allow_unauthenticated_options : false
aors : 107
asymmetric_rtp_codec : false
auth : auth107
bind_rtp_to_media_address : false
bundle : false
call_group :
callerid : “107” <107>
callerid_privacy : allowed_not_screened
callerid_tag :
codec_prefs_incoming_answer : prefer:pending, operation:intersect, keep:all, transcode:allow
codec_prefs_incoming_offer : prefer:pending, operation:intersect, keep:all, transcode:allow
codec_prefs_outgoing_answer : prefer:pending, operation:intersect, keep:all, transcode:allow
codec_prefs_outgoing_offer : prefer:pending, operation:union, keep:all, transcode:allow
connected_line_method : invite
contact_acl :
context : from-internal
cos_audio : 0
cos_video : 0
device_state_busy_at : 0
direct_media : true
direct_media_glare_mitigation : none
direct_media_method : invite
disable_direct_media_on_nat : false
dtls_auto_generate_cert : No
dtls_ca_file :
dtls_ca_path :
dtls_cert_file :
dtls_cipher :
dtls_fingerprint : SHA-256
dtls_private_key :
dtls_rekey : 0
dtls_setup : actpass
dtls_verify : No
dtmf_mode : rfc4733
fax_detect : false
fax_detect_timeout : 0
follow_early_media_fork : true
force_avp : false
force_rport : true
from_domain :
from_user :
g726_non_standard : false
geoloc_incoming_call_profile :
geoloc_outgoing_call_profile :
ice_support : false
identify_by : username,ip
ignore_183_without_sdp : false
inband_progress : false
incoming_call_offer_pref : local
incoming_mwi_mailbox :
language : pr
mailboxes : 107@device
max_audio_streams : 1
max_video_streams : 1
media_address :
media_encryption : no
media_encryption_optimistic : false
media_use_received_transport : false
message_context :
moh_passthrough : false
moh_suggest : default
mwi_from_user :
mwi_subscribe_replaces_unsolicited : no
named_call_group :
named_pickup_group :
notify_early_inuse_ringing : false
one_touch_recording : false
outbound_auth :
outbound_proxy :
outgoing_call_offer_pref : remote_merge
overlap_context :
pickup_group :
preferred_codec_only : false
record_off_feature : automixmon
record_on_feature : automixmon
refer_blind_progress : true
rewrite_contact : true
rpid_immediate : false
rtcp_mux : false
rtp_engine : asterisk
rtp_ipv6 : false
rtp_keepalive : 0
rtp_symmetric : true
rtp_timeout : 0
rtp_timeout_hold : 0
sdp_owner : -
sdp_session : Asterisk
security_mechanisms :
security_negotiation : no
send_aoc : false
send_connected_line : yes
send_diversion : true
send_history_info : false
send_pai : false
send_rpid : false
set_var :
srtp_tag_32 : false
stir_shaken : off
stir_shaken_profile :
sub_min_expiry : 0
subscribe_context :
suppress_q850_reason_headers : false
t38_bind_udptl_to_media_address : false
t38_udptl : false
t38_udptl_ec : none
t38_udptl_ipv6 : false
t38_udptl_maxdatagram : 0
t38_udptl_nat : false
timers : yes
timers_min_se : 90
timers_sess_expires : 1800
tone_zone :
tos_audio : 0
tos_video : 0
transport : transport-udp
trust_connected_line : yes
trust_id_inbound : true
trust_id_outbound : false
use_avpf : false
use_ptime : false
user_eq_phone : false
voicemail_extension :
webrtc : no

What I Have Already Tried:

  1. Disabled SIP ALG on the MikroTik router.
  2. Added NAT settings to pjsip_custom_post.confdirect_media = no
    disable_direct_media_on_nat = yes
    force_rport = yes
    rewrite_contact = yes
    rtp_symmetric = yes
    identify_by = username
    rtp_timeout = 180
    rtp_timeout_hold = 300
    rtp_keepalive = 30
    session_timers = refuse
    timers = no
I would really appreciate any guidance or suggestions. I am stuck and have tried everything I could find online.

Thank you in advance!

You most likely have not configured the public IP address correctly on the transport in Asterisk (you did not provide it), or the ACK is not getting through the NAT to Asterisk. A full SIP trace would confirm what IP address is in the Contact header that the ACK is to be sent to by the remote side.

It’s not due to session timers or rtp_timeout. It’s due to the way that the SIP protocol fundamentally works.

Direct media has no impact on the signaling, and if you’ve disabled it then it’s disabled.

Hello, jcolp.

Yes, I finally found the root cause. It wasn’t the external IP configuration—it was the bind port.

On my MikroTik router, I had NAT configured from a non-standard SIP port to port 5060 on my Issabel server. The problem was that Asterisk was advertising port 5060 in the Contact header of the INVITE request. As a result, the softphone tried to send the ACK to port 5060, but there was no NAT rule for that port, so the request never reached the server.

I changed Asterisk’s bind port to the same external port that was being forwarded by the NAT rule, and that solved the problem completely.

Thank you for your guidance. I hope this solution will also be helpful to anyone else who runs into the same issue.