try hiccup

SIP 488 Not Acceptable Here

Short version: 488 is a verdict on the SDP, not on the call. Something in the offer was unusable at that particular endpoint — usually the codec list, the payload-type mapping, or the transport profile. Read the last offer sent before the 488, not the 488 itself.

What the response actually means

RFC 3261 defines 488 as "some aspect of the session description or the Request-URI is not acceptable here" — at this resource, right now. The "here" is load-bearing: it is the reason 488 exists separately from 606 Not Acceptable, which is the same rejection made on behalf of the user everywhere rather than at one device.

In practice, in ninety-odd percent of traces, 488 means the RFC 3264 offer/answer exchange failed: the answerer could not construct an answer it was prepared to use. Do not confuse it with 415 Unsupported Media Type, which is about the body's content type (the far end could not parse or would not accept application/sdp, or choked on a multipart body), not about its contents.

Read the Warning header first

Many implementations attach a Warning header to the 488, and the three-digit warn-code narrows the search enormously:

What actually causes it

No codec in common

The default suspicion, and it is right often enough. One side offers G.729 only, the other has PCMA/PCMU only, and there is no transcoding licence in between — or there is a transcoder, but the call is taking a path that bypasses it. The tell is that the two m=audio payload-type lists have an empty intersection once you exclude telephone-event and comfort noise, which are not media in their own right and cannot carry the call on their own.

The codec matches but the payload type does not

Dynamic payload types (96–127) are chosen per direction, and strictly speaking each side may number them as it likes. Plenty of equipment is not that liberal. The usual casualty is RFC 4733 telephone-event at PT 101 on one leg and 96 on the other, or an a=fmtp:101 0-15 against 0-16. An SBC that renumbers one leg and forwards the other unchanged produces exactly this.

Secure versus clear media

An offer with m=audio ... RTP/SAVP and a=crypto lines arriving at a leg configured for plain RTP/AVP is unanswerable, and vice versa. Even when both sides do SRTP, the SDES crypto suites have to intersect — AES_CM_128_HMAC_SHA1_80 against a peer offering only ..._32 fails the same way. DTLS-SRTP (UDP/TLS/RTP/SAVP) offered to an SDES-only box is a third variant of the same mismatch.

A T.38 re-INVITE the carrier will not take

Fax calls answer in G.711, then the terminating gateway detects CNG/CED and sends a re-INVITE switching to m=image ... udptl t38. If the trunk does not support T.38, that re-INVITE comes back 488. This is normal and survivable — the gateway is supposed to fall back to G.711 pass-through — but many do not, and the fax dies while the voice call would have been fine. If your 488 happens two to five seconds after answer on a fax number, this is what you are looking at.

An extra media line

Offering video, BFCP or MSRP to a box that handles audio only should produce an answer with that m= line zeroed, not a rejection of the whole session. Not every implementation does the polite thing. The same applies to unexpected a= attributes: ICE, rtcp-mux and bundle attributes are supposed to be ignored when unsupported.

What to check in the trace

  1. Find the last SDP offer before the 488, and confirm which direction it travelled. The 488 answers whoever sent that offer.
  2. Diff the two m= lines and their a=rtpmap / a=fmtp sets side by side. Codec names, payload numbers and fmtp parameters — all three.
  3. Compare the transport profile token on the m= line, and the presence or absence of a=crypto.
  4. Read the Warning header, and any body on the 488: a helpful implementation returns its own capabilities as SDP.
  5. Establish whether the SBC generated the 488 itself or relayed it. A 488 that appears on the ingress leg with no matching failure on the egress leg was made locally, which points at your codec policy rather than the carrier's.
  6. If it is a re-INVITE, check what changed against the original offer. Very often exactly one thing did, and that thing is the answer.

Two nuances worth knowing

A 488 to a re-INVITE does not end the call. RFC 3261 is explicit that when a re-INVITE fails, the session parameters stay as they were, as if it had never been sent. If the call dropped anyway, something above the transaction layer decided to drop it, and that decision is a separate finding.

In a delayed-offer call — an INVITE with no SDP — the offer arrives in the 200 OK and the answer goes in the ACK. There is no response code left to reject with, so the same negotiation failure surfaces as an immediate BYE, often carrying a Reason header, a second or two after answer. If you are hunting a codec problem and cannot find a 488, look for that BYE.

hiccup diffs the two legs of an SBC call automatically and reports codec lists that narrowed, payload types that were renumbered and crypto lines that appeared or vanished — as findings, next to the ladder. Self-hosted, free for individual users.

upload a trace