VoIP

Why Do VoIP Calls Have No Audio? Common Fixes and CLI Troubleshooting

Himanshu Pal

Himanshu Pal

Why Do VoIP Calls Have No Audio? Common Fixes and CLI Troubleshooting

Introduction

The call rings, both sides answer — and then silence. Or worse, one person can hear the other but not the reverse. This is the single most common complaint on any VoIP system running Asterisk, FreePBX, FreeSWITCH or a hosted SIP service, and it is almost never a "broken phone". The signalling worked (the call connected), so the problem is nearly always in the media path — the RTP audio stream — not the SIP that set the call up.

This guide gives you a repeatable way to find and fix it from the Linux command line, using the current PJSIP stack rather than the long-removed chan_sip. Work top to bottom and you will isolate the cause in a few minutes instead of guessing.


The 60-second mental model: SIP vs RTP

Every VoIP call is really two conversations on the wire:

  • SIP (signalling) sets up, modifies and tears down the call. It runs on a known port, usually UDP/TCP 5060 (or 5061 for TLS).

  • RTP (media) carries the actual audio, on a range of dynamically chosen UDP ports negotiated inside the SIP body (the SDP).

Because they are separate flows on different ports, SIP can succeed completely while RTP fails silently. That is exactly what "connected but no audio" is: a media problem masquerading as a call that worked. Ninety percent of the time the root cause is one of three things — NAT rewriting the wrong address, a firewall dropping the RTP port range, or a codec mismatch. The rest of this guide is how to tell which.


A fast diagnostic ladder

Run these in order. Each step rules out a whole class of causes.

Step 1 — Confirm the endpoint is actually registered

asterisk -rx "pjsip show endpoints"
asterisk -rx "pjsip show contacts"

You want to see the endpoint Avail and a contact with a sensible public IP and port. If the contact shows a private 192.168.x.x address for a remote phone, you have found your problem already — jump to the NAT fix below.

Step 2 — Watch the SIP exchange live

asterisk -rx "pjsip set logger on"     # log SIP to the CLI
sudo sngrep                            # or view it interactively

sngrep is the fastest way to read the negotiation. Open the INVITE/200 OK and look at the SDP block — specifically the c= (connection) line and the m=audio port. That address and port are where the far end will send audio. If it is a private IP, RTP is being aimed at a black hole.

Step 3 — Verify RTP is actually flowing (both directions)

asterisk -rx "rtp set debug on"
sudo tcpdump -n -i eth0 udp portrange 10000-20000

During a live call you should see a steady stream of UDP packets in both directions. Packets one way only = one-way audio (a NAT/firewall asymmetry). No packets at all = the whole RTP range is blocked or misrouted.

Step 4 — Confirm a shared codec

asterisk -rx "core show codecs"
asterisk -rx "pjsip show endpoint 7001"   # see the allow= list

If the two ends share no common codec, the call can still connect and then carry no usable audio. Force a safe common codec (see fix 3).


Fix 1 — Configure Asterisk correctly behind NAT (PJSIP)

This is the number-one cause. When your PBX sits behind NAT, it advertises its private IP inside the SDP unless you tell it its public address. Set that on the transport, and turn on the endpoint options that make RTP survive NAT:

; pjsip.conf
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
local_net=192.168.1.0/24
external_media_address=203.0.113.25       ; your PUBLIC IP
external_signaling_address=203.0.113.25

[7001]
type=endpoint
context=from-internal
disallow=all
allow=ulaw
aors=7001
auth=auth7001
direct_media=no          ; keep media anchored on the PBX
rtp_symmetric=yes        ; reply to where RTP actually came from
force_rport=yes          ; reply to the source port, not the SDP port
rewrite_contact=yes      ; trust the real source over the Contact header

Apply and verify:

asterisk -rx "pjsip reload"
asterisk -rx "pjsip show transport transport-udp"

The three endpoint flags — rtp_symmetric, force_rport and rewrite_contact — are what let the PBX ignore the wrong address a NATed phone advertises and send audio back to where the packets genuinely originated. For the deeper why, see what NAT does to SIP and RTP.

On legacy Asterisk (18 and older, chan_sip) the equivalent was nat=force_rport,comedia with externip= and localnet= in sip.conf. Note that chan_sip was removed entirely in Asterisk 21 — if you are on a current release, PJSIP is the only option and the config above is what you want.


Fix 2 — Open the RTP port range on the firewall

SIP on 5060 alone is not enough; the media needs its whole UDP range open. Check what range Asterisk uses:

; rtp.conf
[general]
rtpstart=10000
rtpend=20000

Then allow SIP and that exact range (ufw shown; adjust for firewalld/iptables):

sudo ufw allow 5060/udp
sudo ufw allow 10000:20000/udp
sudo ufw reload

A classic trap: opening 5060 (so calls connect) but forgetting the RTP range (so there is no audio). If your range differs from 10000–20000, open the range in rtp.conf, not a guess. More detail in RTP ports and firewall configuration.


Fix 3 — Pin a common codec

When endpoints cannot agree on an audio format, force a widely-supported one on both sides:

; pjsip.conf endpoint
disallow=all
allow=ulaw
allow=alaw

G.711 (ulaw/alaw) is universally supported and a safe baseline while you diagnose. Once audio is stable you can reintroduce compressed codecs like G.729 or Opus. For the trade-offs, see VoIP codecs compared.


Fix 4 — One-way audio specifically

One-way audio is a directional clue, not a separate bug. Turn on RTP debug and watch which way packets stop:

asterisk -rx "rtp set debug on"

Who can't hear

RTP that's missing

Usual cause

Remote caller hears nothing

PBX → remote

PBX advertising private IP; fix external_media_address

Local phone hears nothing

Remote → PBX

Firewall dropping inbound RTP, or SIP ALG mangling SDP

rtp_symmetric=yes resolves most of these by replying to the address packets actually came from rather than the (wrong) address in the SDP.


Fix 5 — Disable SIP ALG on the router

Many consumer and small-business routers ship with SIP ALG ("SIP Application Layer Gateway") enabled. It tries to rewrite SIP/SDP on the fly and, in practice, corrupts it — producing intermittent no-audio and registration drops that are maddening to trace because the PBX config is correct. Disable it in the router admin (the setting names vary: "SIP ALG", "SIP Transformations", "SIP Helper"). If audio problems appear only for phones behind a particular router, this is the first thing to check.


Fix 6 — Audio that dies after ~30 seconds

If audio is fine and then cuts out around 30 seconds in, you are usually looking at a stateful firewall UDP timeout closing the RTP pinhole, or a SIP session-timer expiring with no keepalive. Keep the NAT mapping alive with qualify_frequency on the AOR (periodic OPTIONS) and make sure the firewall's UDP timeout is longer than your typical silence gaps.

; pjsip.conf aor
[7001]
type=aor
max_contacts=1
qualify_frequency=30

Verify the fix

  • Internal calls fine, external calls silent → almost always NAT or firewall (fixes 1 and 2).

  • Re-run the tcpdump from step 3 and confirm RTP now flows both ways.

  • Use sngrep to confirm the SDP now carries your public IP, not a private one.


FAQ

Q: The call connects but there is no audio at all — where do I start?
A: It is a media (RTP) problem, not signalling. Check the SDP in sngrep for a private IP, then confirm the RTP port range is open on the firewall.

Q: Why one-way audio and not none?
A: RTP is flowing in one direction only — typically the PBX is advertising a private IP outbound, or a firewall is dropping inbound RTP. rtp_symmetric=yes plus a correct external_media_address fixes most cases.

Q: I set everything and it still fails only on one site.
A: Check that site's router for SIP ALG and disable it. It is the most common "the config is right but calls break" cause.

Q: Do I still use nat=yes and sip.conf?
A: Only on Asterisk 18 and older. chan_sip was removed in Asterisk 21; use the PJSIP options shown above.