Skip to content

Voice

Registration failures and NAT

02/11/2026 · 2 min read · Tanveer Ahmed

Applies to Any platform Linux This applies to any SIP phone or PBX behind a NAT firewall; the sngrep and tcpdump commands shown run on Linux.

A phone registers successfully, works for a while, and then stops receiving calls. Outbound still works. This pattern has one dominant cause.

What is happening

When the phone registers, it creates a NAT mapping: an outbound UDP flow that the firewall remembers so replies can return. Inbound calls arrive through that mapping.

NAT mappings for UDP expire. Firewall defaults are commonly 30 to 180 seconds. A phone with a registration expiry of 3600 seconds believes it is registered for an hour, but the mapping vanished minutes after the last packet. The server sends an inbound INVITE to a mapping that no longer exists, and the phone never hears about the call.

Outbound calls still work because the phone creates a fresh mapping when it initiates.

Keeping it open

The phone must send something often enough to keep the mapping alive. Most SIP devices support a keepalive — an OPTIONS request or an empty packet — at a configurable interval. Every 30 seconds is safe against most defaults.

Alternatively, shorten the registration expiry so re-registration itself refreshes the mapping. It is less efficient than a keepalive but uses no special support.

Symmetric response

The server must reply to the source address and port it actually saw, not to what the phone claimed in its Via header. That is rport, and where it is not used or not honoured, replies go to an address that does not exist from the server’s perspective.

SIP ALGs

Many consumer routers include a SIP ALG that rewrites SIP messages. When it works, it helps. When it does not — and implementations vary widely — it corrupts headers in ways that are very hard to diagnose, because the packets you capture at the phone differ from those arriving at the server.

If registration behaves strangely and a consumer router is in the path, disabling the ALG is one of the highest-value things to try.

sngrep                                 # watch registration refresh
tcpdump -nli eth0 port 5060 -A | grep -i 'expires\|contact\|rport'

Related reading