Skip to main content
4 min read

In SIP, what's negotiated isn't what's supported

Three trunks that refused to place a call between two vendors. Each time, a peer that signals one thing and does another. The SBC absorbs it, the trace settles it.

sipsbcinteropaudiocodestelecom

A SIP trunk works in the lab. It breaks in production, between two devices from different vendors. Every time this happened to me, the cause was the same. A peer that signals a capability, a role, or a format, and then does something else. SIP is a contract both sides claim to honor. The implementations diverge.

Three real cases. Three trunks that refused to place a call. Every time, the fix was on the SBC, never on the misbehaving device across the trunk.

What's negotiatedWhat the peer actually doesResult
UPDATE sentUPDATE out of sequence, offer not yet resolvedIgnored, retransmitted in a loop, no calls
refresher=uacThe UAC never refreshesCall dropped when the timer expires
Early Offer expectedThe SBC sends Delayed OfferCall rejected

Case 1: an UPDATE no one was allowed to send

Across the trunk, a Cisco CUBE. On my side, an AudioCodes SBC. The symptom was brutal. No call went through. Zero.

The trace has the answer. The CUBE was sending an UPDATE while the SDP offer from the initial INVITE had not yet received its answer. RFC 3311 forbids it. You do not start a new offer/answer negotiation while the first one is unresolved. AudioCodes does exactly what the RFC asks. It ignores the UPDATE, with no reply.

The CUBE gets no answer, so it retransmits. Again. In a loop. The behavior was systematic on every call, so the trunk stayed down.

The fix: disable UPDATE on the SBC. The initial negotiation completes normally, the call goes through.

Here, the compliant peer is AudioCodes. It followed the RFC to the letter. That did not keep the trunk up. What breaks a trunk is not always a fault in the protocol sense. It's the gap between what one device sends and what the other tolerates.

Case 2: a refresher that never refreshes

My SBC facing an Alcatel-Lucent OXE, the OmniPCX Enterprise. Calls kept dropping. Systematically, always at the same point.

RFC 4028 session timers exist to clear dead calls. Both sides negotiate a Session-Expires and name a refresher, the one that will periodically send a re-INVITE or an UPDATE to signal the call is alive.

Session-Expires: 1800;refresher=uac

The designated refresher was the UAC. The UAC never refreshed. When the timer expired, no one had shown a sign of life. The call was declared dead and cut, while media was flowing both ways.

The fix: move the refresh to the UAS side. The role goes to the party that actually performs it. Calls stop dropping.

Negotiating a role does not guarantee it will be honored. refresher=uac is a promise. The UAC did not keep it. The SBC reassigns the promise to a party that is reliable.

Case 3: Early Offer, or nothing

An AudioCodes SBC sending Delayed Offer, an IPBX across the trunk that requires Early Offer. Call rejected on the spot.

Two ways to present the SDP:

Early Offer   : INVITE + SDP
Delayed Offer : INVITE without SDP, then SDP in the 200 OK

Both are valid. Not every device handles both. This IPBX wanted the offer in the INVITE, period. An INVITE with no SDP, it refuses.

The fix: reconfigure the SBC to send Early Offer. Delayed to Early Offer conversion on AudioCodes. The IPBX gets what it expects, the call sets up.

Valid per the RFC does not mean accepted by the peer. The Delayed Offer was legitimate. It was rejected anyway. The SBC adapts the format to what the other side can read.

What these three cases share

Every time, one side signals one thing and does another. UPDATE out of sequence. Refresher named but idle. Early Offer expected, Delayed Offer sent. Two compliant implementations can still refuse to talk.

Two reflexes come out of this.

You don't fix the vendor across the trunk. I patched neither the CUBE, nor the OXE, nor the IPBX. All three fixes were configs on the SBC. The SBC is the layer where you absorb the peer's reality. That's its job.

The trace is the only truth. The vendor doc says what the device is supposed to do. The SIP capture says what it does. The two don't always agree. Facing a trunk that refuses to work, I don't read a datasheet. I capture, I compare what's negotiated to what happens, and I adapt on the SBC.

A trunk breaking between two vendors, an SBC migration, a go-live stuck on signaling? Get in touch.

Field note by qaryon

Nicolas Marxer

UC/VoIP solution architect focused on operator, integrator, and B2B deployments.

Need a field view on your voice architecture?

Audit, scoping, or deployment: qaryon works directly on SIP, SBC, UCaaS, and automation topics.

Discuss a telecom project