VoIP

The SIP Debugging Checklist: A Systematic Way to Fix Broken Calls

Himanshu Pal

Himanshu Pal

Debug SIP in layers, not in panic

Almost every SIP problem is really one of three problems wearing a disguise: a device that will not register, a call that will not set up, or a call that connects but has no media. The single most useful habit when a call breaks is to decide, before you touch anything, which of those three layers you are in. Guessing across all three at once is how an hour disappears.

This checklist walks the layers in order. Work top to bottom: registration first, because a call cannot set up if the endpoint is not registered; signalling second; media last, because audio only matters once signalling has succeeded.

Step 0: Turn on the right logging first

You cannot debug what you cannot see. Before reproducing the fault, open the Asterisk CLI with high verbosity:

asterisk -rvvvv

Then enable SIP tracing for the stack you actually run. For the modern PJSIP stack:

pjsip set logger on

For the legacy chan_sip stack:

sip set debug on

This prints the full SIP messages — every request and response, with all headers — as they cross the wire. That raw exchange is the ground truth; the friendly log lines above it are only a summary. If you are chasing audio rather than signalling, also turn on RTP debugging:

rtp set debug on

For anything involving NAT, a carrier, or packets you suspect are being altered in transit, capture on the wire as well with sngrep — a live, colour-coded SIP ladder diagram that is far easier to read than raw tcpdump:

sngrep            # live SIP flows
sngrep -d eth0 port 5060

A quick reminder that saves people repeatedly: if you are running behind FreePBX or a similar GUI, changes you make in the web interface are not live until you reload. Read how to read Asterisk logs with rvvv if the console output itself is unfamiliar.

Layer 1 — Registration: is the endpoint even there?

If a phone cannot make or receive calls at all, confirm it is registered before anything else. On PJSIP:

pjsip show endpoints
pjsip show registrations
pjsip show contacts

An endpoint with no Avail contact is not reachable, full stop. When registration fails, the response code tells you which way to look:

  • 401 Unauthorized on the first attempt is normal — it is the authentication challenge, and the device should immediately retry with credentials. Only worry if the 401s never stop, which means the secret is wrong.
  • 403 Forbidden means the credentials were understood and rejected, or the source IP is not permitted. Check the username and secret character-for-character, and confirm the device's IP is allowed if you use an ACL.
  • 408 Request Timeout or no response at all means the REGISTER never reached Asterisk, or the reply never got back. This is a network or firewall problem, not a credentials problem — jump to the firewall notes below.

Two configuration traps account for most "it registered yesterday" cases: a mismatch between the endpoint's context and where your dialplan actually lives, and NAT settings on the endpoint. If the device is behind NAT, it must be told so; otherwise its Contact header advertises a private address the server can never route back to. For a FreePBX-specific walkthrough, see fixing "extension not registered" in FreePBX.

Layer 2 — Signalling: read the response code

Once the endpoint is registered but the call still fails, the SIP response to your INVITE names the cause. Do not skim past it — the first digit alone tells you which side owns the problem. A 4xx points at your configuration; a 5xx points at theirs. The ones you will actually meet:

  • 404 Not Found — the dialled number or extension does not exist on that server. Check the dialplan and the number format: national vs E.164 (+ and country code) trips up carrier routes constantly.
  • 403 Forbidden — on a trunk, almost always wrong credentials, an IP not on the carrier's allow-list, or calling a prefix your account is not permitted to reach.
  • 408 Request Timeout — signalling left but nothing came back in time. Firewall or a dead far end.
  • 480 Temporarily Unavailable — the destination exists but is not reachable now: unregistered device, or Do Not Disturb. Confirm the target's registration first.
  • 488 Not Acceptable Here — a media negotiation failure. The two ends share no common codec, or one side requires encrypted media (SRTP/DTLS) the other is not offering. Compare the allowed codecs on both ends and look at the SDP.
  • 487 Request Terminated — the INVITE was cancelled before answer, normally because the caller hung up or another branch picked up. Expected, not a fault.
  • 503 Service Unavailable — the far end is overloaded, in maintenance, or enforcing a channel limit. On a carrier trunk it often means your concurrent-call ceiling or a suspended account.

Whatever the code, read the accompanying Warning or Reason header if one is present — carriers frequently put the real explanation there while returning a generic 403 or 503. You can look up any code and its practical cause with the SIP response code lookup.

One signalling gremlin deserves its own mention: a 400 Bad Request on an otherwise healthy setup is very often a router's SIP ALG rewriting packets in flight and corrupting headers. If you see malformed messages that look fine leaving your server but wrong on arrival, disable SIP ALG on the router. It causes more problems than it has ever solved.

Layer 3 — Media: the call connects but there is no audio

This is the classic, and it confuses people because the call looks successful. It looks successful because signalling was successful — a 200 OK means the SIP negotiation completed. But audio is RTP, travelling on entirely different UDP ports from the signalling, and it is almost always NAT or a firewall blocking that RTP path that causes one-way or no audio.

Work through these in order:

  • Which direction is missing? One-way audio is the giveaway for NAT. The side that hears nothing is the side whose inbound RTP is being dropped or sent to the wrong address. Two-way silence more often points at a firewall blocking the RTP range entirely, or a codec mismatch that slipped through.
  • Check the SDP connection address. In the INVITE/200 OK, the c= line and the m=audio port declare where each end expects to receive RTP. If a device behind NAT advertises a private c= address (192.168.x.x or 10.x.x.x), its RTP is being sent into a void. This is the root of most one-way audio.
  • Tell Asterisk its public address. On a NATed server, set external_media_address and external_signaling_address in pjsip.conf (or the externip/localnet equivalents in the older stack) so Asterisk rewrites its SDP with a routable address.
  • Open the RTP port range on the firewall. RTP uses a wide UDP range — by default roughly 10000–20000, set in rtp.conf. Every port in that range must be open and forwarded, not just the SIP port 5060. Forwarding 5060 alone gets you a connected call with dead air, every time.
  • Suspect symmetric RTP and direct media. Enabling rtp_symmetric helps with NATed endpoints that send from a different port than they advertise. And if two NATed phones are trying to send RTP straight to each other, turn directmedia off so the media anchors on the server where it can be relayed.

For the deeper NAT mechanics behind all of this, see what NAT means for SIP and VoIP calls, and for a focused fix list, why VoIP calls have no audio.

When the console is not enough: capture the packets

If the Asterisk logs look clean but calls still fail, the problem is between machines and you need to see the wire. Three tools, in increasing depth:

  • sngrep — start here. It shows SIP dialogs as ladder diagrams in real time and lets you drill into any message. Ninety per cent of "the logs look fine" cases are solved here, because you can see what actually arrived versus what was sent.
  • tcpdump — when you need a capture to keep or open elsewhere: tcpdump -i any -s 0 -w /tmp/sip.pcap port 5060 or portrange 10000-20000. That grabs both signalling and media for offline analysis.
  • Wireshark / Homer — for the hard cases. Wireshark's Telephony > VoIP Calls reconstructs and even plays back the RTP, which instantly proves whether audio packets are flowing and in which direction. Homer (sipcapture) is worth deploying if you run SIP at any scale and want history rather than a live window.

The quick checklist

When a call breaks and you have thirty seconds before someone asks "is it fixed yet," run this:

  1. Decide the layer: registration, signalling, or media?
  2. pjsip set logger on (or sip set debug on) and reproduce it.
  3. Registered? pjsip show contacts — no contact, no call.
  4. Read the SIP response code. 4xx is your side, 5xx is theirs.
  5. 488? Codec or SRTP mismatch — compare the SDP.
  6. Connected but silent? It is RTP: check the SDP c= address, the server's external address, and the firewall's UDP RTP range.
  7. One-way audio is NAT until proven otherwise.
  8. Logs clean but still broken? sngrep and watch the real packets.

Frequently asked questions

How do I enable SIP debugging in Asterisk?

Connect with asterisk -rvvvv, then run pjsip set logger on for the PJSIP stack or sip set debug on for chan_sip. Both print the full SIP message exchange. Add rtp set debug on to trace media.

Why does my SIP call connect but have no audio?

Signalling and media are separate in SIP. A connected call means signalling succeeded; audio is RTP on different UDP ports. No audio is almost always NAT or a firewall dropping RTP — check the SDP connection address, set the server's external address, and open the RTP port range (typically 10000–20000), not just port 5060.

What does SIP 488 Not Acceptable Here mean?

The two ends could not agree on media — no shared codec, or one side requires encrypted media the other is not offering. Compare the allowed codecs and inspect the SDP in a trace.

Is 401 Unauthorized during registration a problem?

Not on its own. The first 401 is the normal authentication challenge, and the device should retry with credentials. Continuous 401s that never succeed mean the password is wrong.

What is SIP ALG and should I disable it?

SIP ALG is a router feature that rewrites SIP packets as they pass through. It is meant to help with NAT but frequently corrupts headers, producing malformed messages and 400 Bad Request errors. On most setups the fix for mysterious SIP breakage is to disable it.