VoIP Troubleshooting Guide

Kamailio SIP Troubleshooting

9 min read  ·  Updated April 2026

Kamailio is one of the most powerful SIP proxies available — and one of the most complex to debug. When calls aren't routing correctly, registrations fail, or transactions time out, the answers are in the logs and in the routing script. Here's how to find them efficiently.

In this guide

1. Enabling debug logging

Kamailio's logging is configured in kamailio.cfg. The debug level controls verbosity from 1 (errors only) to 5 (full debug):

; In kamailio.cfg — global parameters debug=3 # debug level (3=info, 5=full debug) log_stderror=no # log to syslog (yes for console in testing) log_facility=LOG_LOCAL0 log_name="kamailio" ; Change at runtime without restart kamcmd cfg.set_now_int core debug 5

Key log categories

; View logs (systemd) journalctl -u kamailio -f ; View logs (syslog) tail -f /var/log/syslog | grep kamailio ; Filter by transaction grep "Call-ID: abc123" /var/log/syslog

2. Using xlog for script debugging

xlog is Kamailio's logging function for the routing script. It's the primary tool for understanding why a request is being routed a certain way:

; Add xlog statements to your routing script request_route { xlog("L_INFO", "[$ci] Received $rm from $si:$sp to $ru "); if (is_method("REGISTER")) { xlog("L_INFO", "[$ci] REGISTER from $fu to $tu "); if (!auth_check("$fd", "subscriber", "1")) { xlog("L_WARN", "[$ci] Auth failed for $fu "); auth_challenge("$fd", "0"); exit; } xlog("L_INFO", "[$ci] Auth passed for $fu "); } }

Useful xlog variables

$ci = Call-ID $rm = Request method (INVITE, REGISTER, etc.) $si = Source IP address $sp = Source port $ru = Request URI $fu = From URI $tu = To URI $fd = From domain $td = To domain $rs = Response status code $rr = Response reason phrase

3. SIP trace capture with siptrace

Kamailio's siptrace module captures full SIP transactions to a database or Homer SIP capture server. This is the most effective way to collect traces for analysis:

; Load siptrace module in kamailio.cfg loadmodule "siptrace.so" modparam("siptrace", "duplicate_uri", "sip:homer-server:9060") modparam("siptrace", "hep_mode_on", 1) modparam("siptrace", "hep_version", 3) modparam("siptrace", "trace_on", 1) ; In routing script — trace specific calls request_route { sip_trace(); # trace this request }

Alternative: ngrep for quick captures

; Capture all SIP traffic on interface ngrep -W byline -d eth0 port 5060 ; Capture traffic from specific IP ngrep -W byline -d eth0 host 192.168.1.100 and port 5060 ; Write to file for analysis ngrep -W byline -d eth0 -O /tmp/capture.pcap port 5060

4. Common routing failures

Issue 01
REGISTER not reaching the registrar
Add xlog before and after your registrar routing logic. Check that the domain in the To header matches a domain Kamailio considers local (is_myself()). If is_myself() returns false for the domain, Kamailio will try to forward the REGISTER rather than process it locally. Check your domain list with kamcmd domain.dump.
Issue 02
INVITE not finding registered contact
If lookup() returns false, the AOR isn't in the location table. Check with kamcmd ul.dump to see registered contacts. Verify the contact expiry hasn't passed. Check that the AOR format in the INVITE Request-URI matches exactly how it was registered (case sensitive, including domain).
Issue 03
407 Proxy Authentication loops
If INVITE is triggering proxy auth and the UA doesn't support 407 (only 401), or if the proxy auth realm doesn't match what the UA expects, you'll see authentication loops. Check proxy_auth_check() parameters and ensure the realm matches the UA configuration.
Issue 04
Route header causing loop
Malformed Route headers or Record-Route processing can cause requests to loop back to Kamailio. Check that loose_route() is called correctly at the start of request_route for in-dialog requests. Use xlog to print $route(1) and trace where the request is being sent.

5. Database-related issues

Kamailio relies heavily on database connections for subscriber auth, location, dialplan, and other modules. Database issues produce 500 errors or silent failures:

; Check database connectivity kamcmd ul.stats # location table stats kamcmd dispatcher.list # dispatcher entries (if used) ; Test auth database directly mysql -u kamailio -p kamailio -e "SELECT * FROM subscriber LIMIT 5;" ; Check for connection errors in logs grep -i "db\|database\|mysql\|postgresql" /var/log/syslog | tail -20

Common database issues: connection pool exhaustion under high load (increase db_pool_size), stale connections being reused after database restart (enable db_reconnect), and slow queries causing transaction timeouts (add indexes on username and domain columns in subscriber table).

6. Analyzing Kamailio captures with SIPSymposium

Export your Kamailio siptrace captures or ngrep PCAP files and upload them directly to SIPSymposium. The analyzer reconstructs the SIP dialogs, identifies routing issues, authentication failures, and timing problems across all transactions in the capture.

Kamailio's high-performance routing means it's often handling thousands of simultaneous transactions — SIPSymposium's multi-endpoint correlation is particularly useful for isolating a specific call's behavior from the background noise of a busy proxy.

Frequently asked questions

How do I enable debug logging in Kamailio?

Set debug=5 in kamailio.cfg global parameters for maximum verbosity. View logs with journalctl -u kamailio -f or tail -f /var/log/syslog | grep kamailio. To change log level at runtime without restart use kamcmd cfg.set_now_int core debug 5. Use xlog() in your routing script to add custom debug messages with variable values.

How do I debug Kamailio registration failures?

Add xlog statements before and after your auth_check() call to see what credentials are being presented. Use kamcmd domain.dump to verify domains Kamailio considers local. Check that is_myself() returns true for the registration domain. Use kamcmd ul.dump to see registered contacts and verify AOR format matches. Check database connectivity if using DB-backed subscriber authentication.

How do I reload Kamailio configuration without dropping calls?

For most module config changes use kamcmd cfg.reload. For routing script changes you need a full reload with kamailio reload or kill -HUP $(pidof kamailio). For dispatcher destinations use kamcmd dispatcher.reload. For dialplan changes use kamcmd dialplan.reload. Plan restarts during low-traffic windows as active calls may be affected.

Debugging a Kamailio routing issue?

Upload your Kamailio siptrace or PCAP to SIPSymposium. The analyzer reconstructs SIP dialogs from high-volume proxy captures and identifies routing failures, authentication issues, and transaction timing problems.

Analyze my trace Create free account
Related guides