Identify the method, transaction and responder
Capture one complete failed exchange with the Call-ID, CSeq method and number, top Via branch, request URI, Route set, source and destination. Establish whether Asterisk received 500 Server Internal Error from a phone, proxy or provider, or generated 500 while acting as the server. RFC 3261 says 500 represents an unexpected condition that prevented that server from fulfilling the request; it does not name the condition.
Keep INVITE, REGISTER, OPTIONS and in-dialog requests separate. Preserve the response reason phrase and any Retry-After value, but do not treat a customized phrase as a standardized root cause. A received 500 is evidence about the responder on that transaction, not proof that Asterisk itself crashed or exhausted CPU.
Preserve the SIP response before cause translation
Use a narrow pjsip set logger on reproduction and correlate it with the Asterisk log by timestamp, Call-ID and channel. Disable protocol logging when the capture ends and protect credentials, identities and SDP. The wire response is the primary evidence for its source and method.
Asterisk's published mapping associates SIP 500 with AST_CAUSE_NETWORK_OUT_OF_ORDER and also maps broader 5xx responses to switching congestion. Those translations are intentionally coarser than the original SIP exchange. When dialplan evidence is required, use HANGUPCAUSE_KEYS() and HANGUPCAUSE(channel,tech) or tech_extended alongside the Asterisk cause; do not reconstruct an exact 500 solely from a generic cause or DIALSTATUS.
Diagnose a received 500 on the outbound leg
For an outbound INVITE, first verify the selected endpoint, outbound proxy or Route, resolved next hop and the exact peer that sent the response. Then compare the provider or proxy evidence for the same Call-ID. Dial() may report CONGESTION or another coarse result after a failed attempt, but that value does not identify which 5xx arrived or which downstream component failed.
Check the responder's log, route or application state for the matching method and time. Correct only the demonstrated peer, policy, request formatting or downstream dependency. Do not change codecs, credentials, NAT, firewall rules and dialplan together, and do not turn one upstream 500 into a claim that every destination or call direction is unavailable.
Investigate a 500 generated by Asterisk locally
When the trace shows Asterisk emitted 500, inspect the first specific error or warning for the same request before restarting anything. Bind it to the loaded endpoint, dialplan context, application or module and confirm whether the request reached the expected handler. Recent configuration, module, database and resource events are candidates only when their timestamps and request path match.
Asterisk can also translate a local network-out-of-order cause to SIP 500. That mapping still does not establish the original source of the cause or prove a hardware, interface or carrier failure. Preserve the local channel and any downstream leg so that an incoming 500 response is not mislabelled as a newly generated application exception.
Treat outbound REGISTER as a separate retry state
Asterisk documents 500 as a temporary outbound-registration failure, alongside no response, 408, 502, 503, 504 and 600-class responses. The registration follows its loaded retry_interval and max_retries; the current guide lists defaults of 60 seconds and 10 retries. Read the loaded registration and preserve one failure before changing either value.
RFC 3261 allows a temporary 500 to include Retry-After, but the reviewed Asterisk registration guide documents its own retry settings rather than promising a universal Retry-After behavior. Do not create an aggressive retry loop, and do not infer that a REGISTER failure explains an unrelated INVITE without evidence connecting the objects and time.
Keep intentional PJSIP final responses version-sensitive
Current supported Asterisk documentation includes PJSIPHangup(), which can terminate an incoming PJSIP channel with a selected 400–699 response. The application is documented for specific maintained branches and must run before any other final response such as an answer. An intentionally emitted 500 can therefore be dialplan policy, but only if the running branch and dialplan prove it.
Do not add PJSIPHangup(500) as a generic repair or conceal a specific application error behind it. On FreePBX, generated dialplan ownership and supported custom contexts remain separate constraints; preserve managed configuration rather than editing generated files.
Prove one narrow correction and recovery
Correct the evidenced fault at the component that emitted or caused the response, then repeat the same method, destination and call direction. Confirm the new final response, expected registration or call result, two-way media where a call connects, release behavior and a nearby control. If the responder is external, provide the provider with UTC time, redacted identities, Call-ID, method, source and destination and the received response.
A successful retry proves that bounded transaction recovered, not that capacity, every route, failover or future requests are healthy. No PBX, endpoint, provider, proxy, registration, dialplan, application, resource, failover or live-call behavior was tested for this guide.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- IETF RFC 3261: SIP 500 and Retry-After ↗
- Asterisk outbound registration failure handling ↗
- Asterisk PJSIP troubleshooting guide ↗
- Asterisk hangup cause mappings ↗
- Asterisk per-channel hangup cause inspection ↗
- Asterisk Dial application results ↗
- Asterisk PJSIPHangup application ↗
- Asterisk debug-information collection ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.