Howwise RSS
VoIP & Phone Systems8 min read

VoIP Incoming Calls Not Ringing but Phone Registered: Fixes

Short answer

VoIP incoming calls not ringing on a registered phone means outbound REGISTER works while the inbound INVITE fails at another layer. Capture the INVITE with pjsip set logger on or sngrep, then fix the layer where it stops or gets rejected.

Key takeaways
  • Registered only proves your REGISTER reached the server; inbound INVITEs need a trunk match, a DID match, a live contact and an open return path.
  • Place a test call while running sngrep or 'pjsip set logger on' first: whether the INVITE arrives, and what response it gets, tells you which layer is broken.
  • Idle NAT pinholes close in 30 to 60 seconds, so set qualify_frequency 20 to 30 to keep UDP bindings alive.
  • Firewall ACCEPT rules must be inserted with -I above any DROP or fail2ban rules, and verified with iptables -S INPUT, or they may never match.
  • Straight-to-voicemail with a healthy network is usually DND, forwarding, a short ring timeout, a time condition or a failover destination.

Why are VoIP incoming calls not ringing when the phone shows registered?

When VoIP incoming calls are not ringing but the phone shows registered, the cause is almost never the registration itself. Registration is one SIP transaction: the phone or PBX sends REGISTER, the registrar stores a binding (Address of Record mapped to a Contact URI) and answers 200 OK. It proves credentials were accepted and that outbound packets reached the server. It proves nothing about the reverse direction.

An inbound call is a different INVITE that must pass five gates: it must reach your server (provider, firewall, NAT), be matched to a trunk, match an inbound route by DID, resolve to an extension with a live contact, and finally reach the device on a routable Contact address. Any one can fail while the registered indicator stays green.

Two setups behave differently. With a PBX such as FreePBX, the phone registers to the PBX and the PBX registers to (or is IP-authenticated by) the provider, so there are two registrations to check. With a phone registered directly to a provider, only the provider binding and your NAT matter.

How do I see whether the INVITE even arrives?

Do this first, before changing any setting. Place an inbound call from a mobile while watching the signaling live. The result splits the problem cleanly in two.

  1. Open the CLI with asterisk -rvvv and enable PJSIP logging with pjsip set logger on.
  2. Call your DID from an outside phone.
  3. If you see INVITE from the provider IP, note the response your server sends: 100, 180, 401, 403, 404, 480, 503.
  4. If you see nothing, capture on the wire with sngrep or tcpdump to see whether packets reach the NIC at all.
  5. Turn logging off afterwards with pjsip set logger off; it is verbose and can fill logs.
asterisk -rvvv
pjsip set logger on

# on the host, independent of Asterisk
sngrep -d any port 5060
tcpdump -ni any -s0 port 5060 or port 5061

# state checks
pjsip show registrations
pjsip show endpoints
pjsip show contacts
pjsip show identifies
Tip: If tcpdump sees the INVITE but Asterisk logs nothing, the packet is being dropped by the host firewall or bound to a different interface or port. If tcpdump sees nothing, the problem is upstream of your server.

Which layer is failing? Triage by outcome

Match what you saw to the table. Each row names the signature and the fix, and the order follows the packet's path.

What you seeLikely causeFix
No INVITE on tcpdumpProvider not sending: registration expired, wrong IP whitelisted, DID not pointed at your accountCheck pjsip show registrations; update your public IP at the provider; confirm DID routing in their portal
INVITE arrives, no reply, no logFirewall, fail2ban or iptables dropping 5060Check iptables -S INPUT, fail2ban-client status, allow provider ranges
INVITE answered 401 then droppedTrunk not identified, so treated as an unknown caller and challengedAdd identify section with the provider IPs, or match by username
403 ForbiddenACL or permit/deny block, or wrong authReview endpoint ACL and fail2ban bans
404 Not FoundUnknown DID or no matching inbound routeFix DID format; add a route; see next section
Log: Call from '' rejected / Rejecting unknown SIP connectionTrunk match failed, call fell into the anonymous contextDefine identify_by or an identify entry
480 Temporarily UnavailableExtension has no contact or contact expiredCheck pjsip show contacts; fix keepalive or re-register
503 Service UnavailableContact unreachable or all channels failingCheck NAT, Contact IP and qualify status
408 Request TimeoutINVITE sent to a dead private or stale ContactFix NAT settings, remove stale contacts
Rings briefly, then voicemailNo answer, busy, DND, forwarding or failoverCheck extension and inbound route destinations

How do I fix DID and trunk matching?

Providers send the called number in different forms: +1NXXNXXXXXX, 1NXXNXXXXXX, 10 digits, or a SIP username instead of a number. FreePBX matches the Request-URI user part against the inbound route's DID field exactly, so a route set to 5551234567 will not match +15551234567.

The quickest test is a catch-all route with Any DID and Any CID, pointing at a known extension. If calls ring through it, the DID format is the problem. Read the real value from the logged INVITE line, then add a route using exactly that string, or use the provider's number-format option or a pattern such as _+1NXXNXXXXXX.

Asterisk must also decide which endpoint the INVITE belongs to. PJSIP tries identifiers in the order set by identify_by on the endpoint. Unmatched requests go to the anonymous endpoint, are challenged with 401, and are dropped when no anonymous endpoint exists.

; /etc/asterisk/pjsip_custom.conf (FreePBX) - IP-based match
[provider-identify]
type=identify
endpoint=provider-trunk
match=203.0.113.10
match=203.0.113.11

[provider-trunk]
type=endpoint
identify_by=ip,username,auth_username
; If the provider has no fixed IPs and puts your username in the From
; header of inbound INVITEs, rely on username matching instead: the
; endpoint section name (here provider-trunk) must equal that From user,
; or use auth_username to match the auth username.
; Do not use from_user for this: it only sets the From user on OUTBOUND
; calls and has no effect on how inbound INVITEs are identified.
context=from-pstn
disallow=all
allow=ulaw,alaw
Tip: Search the log for 'Rejecting unknown SIP connection' and 'Call from '' rejected'. Both mean the trunk was not identified, and the DID is irrelevant until that is fixed.

Registration trunk or IP authentication: what breaks inbound?

A registration trunk needs a live REGISTER to the provider. If it is Rejected or Unregistered in pjsip show registrations, the provider has no place to send calls, so inbound dies while outbound may still work. Lower the registration expiration to 120 or so, so a drop recovers quickly, and set retry_interval.

An IP-authenticated trunk has no registration. The provider sends to your public IP, and you must allow their ranges while they must whitelist yours. A dynamic WAN IP that changes silently breaks inbound: outbound still works if the provider authenticates by credentials. Compare curl ifconfig.me against the IP in the provider portal, and use a dynamic DNS feature or static IP if offered.

Also confirm the provider sends to the port you listen on, commonly UDP 5060, or TCP/TLS 5061.

Why do calls stop ringing after a few minutes (NAT and keepalive)?

When a phone behind NAT registers, the router opens a UDP pinhole. Many routers close idle UDP mappings after 30 to 60 seconds, while the registration may last 3600 seconds. The server still believes the contact is valid, but its INVITE hits a closed pinhole. Result: rings right after a reboot, then silence.

The fix is to send traffic more often than the NAT timeout. In PJSIP, qualify_frequency of 20 to 30 makes Asterisk send OPTIONS and keep the mapping open (chan_sip uses qualify=yes). You can also shorten the phone's register expiry to 60 to 120 seconds or enable its keepalive.

The Contact must be routable. If a phone advertises a private Contact (192.168.x.x) and the server is remote, INVITEs go to the wrong place. Rewriting the contact to the observed source fixes it.

[100]
type=endpoint
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
direct_media=no

[100]
type=aor
max_contacts=1
remove_existing=yes
qualify_frequency=25
minimum_expiration=60

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
external_media_address=198.51.100.5
external_signaling_address=198.51.100.5
local_net=192.168.1.0/24
Warning: Disable SIP ALG on the router. It rewrites SIP headers badly and causes missing ring, one-way audio and broken re-registration. Only change firewall rules after noting the current ones, and never open 5060 to the whole internet.

Firewall rules and fail2ban

Allow SIP only from the provider's published ranges, plus your LAN or VPN for phones. Typical needs are UDP/TCP 5060 (or 5061 TLS) and RTP UDP 10000 to 20000. If fail2ban banned the provider after a few failed matches, inbound stops with no log in Asterisk.

Rule order matters. iptables evaluates INPUT top to bottom, so an ACCEPT appended with -A lands after any existing DROP or fail2ban chain jump and may never match. Use -I INPUT to insert the rules at the top, then run iptables -S INPUT to confirm they sit before the drop rules.

The snippet below covers UDP 5060, TCP 5060 and TCP 5061 (TLS) from the provider range, plus RTP. Delete the lines for transports your provider does not use. Each -I places the rule at position 1, so the last one you run ends up first; that is fine, as long as all precede the DROP.

Check the result with iptables -S INPUT and fail2ban-client status, and unban the provider IP if it is listed.

# insert (-I), not append (-A), so the rules sit above any DROP / fail2ban rules
iptables -I INPUT -p udp -s 203.0.113.0/24 --dport 5060 -j ACCEPT
iptables -I INPUT -p tcp -s 203.0.113.0/24 --dport 5060 -j ACCEPT
iptables -I INPUT -p tcp -s 203.0.113.0/24 --dport 5061 -j ACCEPT
iptables -I INPUT -p udp -s 203.0.113.0/24 --dport 10000:20000 -j ACCEPT

# verify order: the ACCEPT lines must appear before any DROP or f2b-* jump
iptables -S INPUT

fail2ban-client status asterisk
fail2ban-client set asterisk unbanip 203.0.113.10
Warning: Rules added with iptables are lost on reboot unless saved with your distribution's persistence tool. On a remote server, keep your SSH rule above any new DROP so you do not lock yourself out.

Softphones and voicemail: when the network is fine

iOS and Android kill background sockets, so a softphone only rings with the app open unless push works. The PBX or a push gateway must send APNs or FCM to wake the app, which then re-registers. Check notification permission, battery optimisation, Do Not Disturb and that the push is configured. Stale contacts from earlier installs can also receive forks; remove them with max_contacts and remove_existing.

If the INVITE reaches the extension and goes to voicemail, look at the PBX: DND, call forwarding on busy or no answer, a ring timeout that is too short, a Call Flow Control toggle or Time Condition in night mode, or a failover destination on the inbound route. These are configuration, not network.

Common questions

Why do incoming calls go straight to voicemail on VoIP?

The extension is likely unreachable (no contact, 480), DND or forwarding is set, or the ring timeout is near zero. Check pjsip show contacts and the extension's follow-me and voicemail settings.

Why does FreePBX say inbound calls are not ringing the extension?

Usually the inbound route does not match the DID, so the call falls to a catch-all or the failover. Add an Any DID route as a test and read the DID in the logged INVITE.

What does pjsip show contacts status Unavail or NonQual mean?

Unavail means qualify OPTIONS got no reply, so the path is dead or blocked. NonQual means qualifying is off, so Asterisk cannot detect a dead NAT mapping.

Do I need to open port 5060 to the whole internet?

No. Restrict it to the provider's IP ranges and your own network, because open SIP gets scanned and brute forced within hours.

Can a changed public IP break only inbound calls?

Yes. With IP authentication the provider still sends to the old address, while outbound with credentials keeps working.

Related topics:voipasteriskfreepbxsipnat