Master the complete diagnostic and resolution process for SIP 408 errors in ViciDial and Asterisk production environments, covering network analysis, firewall rules, SIP configuration tuning, and carrier-level debugging.
Prerequisites
Before diving into this tutorial, ensure you have:
- A running ViciDial/Asterisk installation (tested on 2.14+)
- SSH access to your Asterisk server with sudo privileges
- Basic understanding of SIP protocol and VoIP concepts
- Network diagnostic tools:
tcpdump,netstat,iptables - Access to
/etc/asterisk/configuration directory - ViciDial database access (MySQL/MariaDB)
- Knowledge of your carrier's SIP trunk details
- Ability to check firewall rules and NAT configuration
Understanding SIP 408 Request Timeout
What Is SIP 408?
The SIP 408 (Request Timeout) response indicates that the Asterisk server did not receive a response from the remote SIP endpoint (usually your carrier's SIP trunk) within the expected timeframe. This is fundamentally different from call failures caused by rejection—the server is simply not answering.
Common Scenarios in ViciDial
- Outbound calls hang: Agents see "no answer" or calls drop during routing
- Inbound calls fail: DIDs receive no connection attempts from carrier
- Intermittent issues: Timeout occurs randomly, typically under load
- Carrier-specific problems: One carrier works, another doesn't
The root cause is always one of these categories:
- Network connectivity issues (firewall blocking, NAT misconfiguration)
- SIP timeout values too aggressive for your infrastructure
- Asymmetric routing or packet loss
- Carrier not properly configured or experiencing issues
- DNS resolution failures
- RTP port range problems
Network Diagnostics: Foundational Steps
Step 1: Verify Basic Connectivity
Start by confirming your Asterisk server can reach your SIP carrier:
# Test carrier IP/hostname resolution
nslookup sip.yourcarrier.com
dig sip.yourcarrier.com +short
# Ping the carrier (may be disabled by carrier, but worth trying)
ping -c 5 203.0.113.50
# Test SIP port connectivity with nc (netcat)
nc -zv 203.0.113.50 5060
nc -zv 203.0.113.50 5061
# More detailed test with timeout
timeout 5 bash -c 'echo > /dev/tcp/203.0.113.50/5060' && echo "Port 5060 is open" || echo "Port 5060 is closed"
Step 2: Check Asterisk Binding
Verify that Asterisk is properly binding to the correct interface:
# View all SIP ports Asterisk is listening on
netstat -tlnp | grep asterisk | grep -E '5060|5061'
# Example output should show:
# tcp 0 0 0.0.0.0:5060 0.0.0.0:* LISTEN 1234/asterisk
# udp 0 0 0.0.0.0:5060 0.0.0.0:* 1234/asterisk
If Asterisk is only binding to 127.0.0.1 or a specific internal IP, external carriers cannot reach it.
Step 3: Analyze Outbound Packet Flow
Use tcpdump to capture SIP packets and identify where the conversation breaks:
# Capture SIP traffic to/from your carrier
tcpdump -i any -n -s 0 -vvv host 203.0.113.50 and port 5060 -w /tmp/sip_capture.pcap
# In another terminal, initiate a test call, then stop capture with Ctrl+C
# View the capture in human-readable format
tcpdump -r /tmp/sip_capture.pcap -vvv | head -100
# Count SIP messages by type
tcpdump -r /tmp/sip_capture.pcap | grep -oE 'SIP/2.0 [A-Z]+ |^[A-Z]+ sip:' | sort | uniq -c
Look for this pattern:
INVITE sent to carrier (your server → carrier)
100 Trying received from carrier (carrier → your server)
INVITE TIMEOUT (no 183/180/200 response)
BYE sent (cleanup)
If you see INVITE but no response, the issue is almost certainly carrier-side or network-path related.
Step 4: Monitor Real-Time SIP Sessions
While making test calls, observe Asterisk's SIP channel state:
# SSH to Asterisk server
asterisk -rx "sip show channels" | grep -E 'Channel|TO|FROM'
# Example output:
# Channel State Type Exten Context
# SIP/carrier-0000001f DOWN INVITE s from-external
# Get detailed info on a specific channel
asterisk -rx "sip show channel SIP/carrier-0000001f"
Firewall Configuration & NAT
Understanding the Firewall Problem
The most common cause of 408 timeouts in production ViciDial systems is asymmetric firewall rules or NAT configuration. Your outbound packets reach the carrier, but their responses are blocked coming back.
Firewall Rules: Bulletproof Configuration
# First, determine your internal IP and external carrier IP
# Internal SIP IP (usually private):
ip addr show | grep "inet " | grep -v 127.0.0.1
# External interface (usually eth0, ens0, etc.):
ip route | grep default
# Check current iptables rules
iptables -L -n -v | grep -E '5060|5061|10000:20000'
# If using UFW (Ubuntu/Debian):
ufw status
Proper firewall rules for a ViciDial system:
# Allow SIP from your carrier (CRITICAL)
iptables -I INPUT -p udp --dport 5060 -s 203.0.113.50 -j ACCEPT
iptables -I INPUT -p tcp --dport 5060 -s 203.0.113.50 -j ACCEPT
iptables -I INPUT -p udp --dport 5061 -s 203.0.113.50 -j ACCEPT
iptables -I INPUT -p tcp --dport 5061 -s 203.0.113.50 -j ACCEPT
# Allow RTP audio stream (critical!)
iptables -I INPUT -p udp --dport 10000:20000 -s 203.0.113.50 -j ACCEPT
# Allow established/related connections
iptables -I INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow loopback (internal communication)
iptables -I INPUT -i lo -j ACCEPT
# Outbound: Allow SIP to carrier
iptables -I OUTPUT -p udp --dport 5060 -d 203.0.113.50 -j ACCEPT
iptables -I OUTPUT -p tcp --dport 5060 -d 203.0.113.50 -j ACCEPT
iptables -I OUTPUT -p udp --dport 5061 -d 203.0.113.50 -j ACCEPT
iptables -I OUTPUT -p tcp --dport 5061 -d 203.0.113.50 -j ACCEPT
# Allow RTP outbound
iptables -I OUTPUT -p udp --dport 10000:20000 -d 203.0.113.50 -j ACCEPT
# Save rules permanently (iptables-persistent)
iptables-save > /etc/iptables/rules.v4
UFW Configuration (Modern Ubuntu/Debian)
# Enable UFW if not already
sudo ufw enable
# Allow from carrier (replace with your carrier IP)
sudo ufw allow from 203.0.113.50 to any port 5060 proto udp
sudo ufw allow from 203.0.113.50 to any port 5061 proto tcp
sudo ufw allow from 203.0.113.50 to any port 10000:20000 proto udp
# Allow SSH to not lock yourself out
sudo ufw allow ssh
# Check active rules
sudo ufw status verbose
NAT Configuration
If your ViciDial server is behind NAT, Asterisk must know its public IP:
# Edit main SIP config
nano /etc/asterisk/sip-vicidial.conf
# Find or add these lines under [general]:
externip = 203.0.113.100 ; Your PUBLIC IP (not carrier IP)
localnet = 192.168.1.0/24 ; Your INTERNAL network
nat = yes ; Enable NAT processing
If using a dynamic public IP (not recommended for production), use:
[general]
externhost = mypublicip.dyndns.org
localnet = 192.168.1.0/24
nat = yes
After NAT changes, reload Asterisk:
asterisk -rx "sip reload"
Asterisk SIP Configuration Tuning
Aggressive vs. Conservative Timeout Values
The default SIP timeout in Asterisk (6 seconds) is too aggressive for international carriers or congested networks. ViciDial's default is better, but still needs tuning.
# Backup current config
cp /etc/asterisk/sip-vicidial.conf /etc/asterisk/sip-vicidial.conf.backup.$(date +%s)
# Edit the main SIP configuration
nano /etc/asterisk/sip-vicidial.conf
Add or modify these parameters in the [general] section:
[general]
; === Timeout Configuration ===
; Default SIP invite timeout in milliseconds (default: 6000)
; For unstable/international carriers, increase to 15000-30000
sip_t1 = 500 ; Initial timeout between retransmissions (ms)
sip_t1min = 100 ; Minimum T1 value (ms)
sip_invite_timeout = 30 ; Timeout for INVITE responses (seconds)
sip_register_timeout = 20 ; Registration timeout
; === Retransmission Policy ===
; Number of retransmissions before giving up
; Default is usually 6, which means ~32 seconds total
; For ViciDial production: 8-10 is safer
max_retries = 8
; === Connection Management ===
; Timeout for idle connections (seconds)
; Prevents phantom timeouts from long-lived connections
tcp_connect_timeout = 10
tcp_read_timeout = 10
; === Keep-Alive / Session-Timer ===
; Enable session timers to refresh connection state
session_timer = 1800 ; Session timer in seconds (30 minutes)
session_refresher = uas ; Who refreshes: uas, uac, or auto
session_expires = 1800
min_se = 90
; === Other Critical Settings ===
; Disable aggressive NAT if you've configured externip correctly
directmedia = no ; Force media through Asterisk (safer)
nat = yes ; Enable NAT mode
qualify = 100 ; Send OPTIONS to peers every 100ms
qualify_timeout = 2 ; Timeout for qualify (seconds)
Carrier-Specific Configuration
Each carrier endpoint needs its own timeout values. In the [carrier_name] sections:
[mycarrier]
type = peer
host = sip.mycarrier.com
port = 5060
context = from-carrier
fromdomain = mycarrier.com
fromname = ViciDial-System
disallow = all
allow = ulaw,alaw
insecure = port,invite
nat = yes
directmedia = no
; Carrier-specific timeouts
sip_t1 = 1000 ; Longer initial timeout for this carrier
sip_invite_timeout = 45 ; Very tolerant timeout
qualify = yes
qualify_timeout = 3 ; Longer qualify timeout
Check Configuration Syntax
Before reloading, validate the configuration:
# Validate SIP config
asterisk -C /etc/asterisk/asterisk.conf -n
# If valid, reload SIP module
asterisk -rx "sip reload"
# Verify the changes took effect
asterisk -rx "sip show settings" | grep -i timeout
ViciDial-Specific Configuration
Update ViciDial Carrier Settings via Database
Some timeout settings are stored in the ViciDial database, not Asterisk config:
# Access ViciDial database
mysql -u root -p asterisk
-- View your carriers
SELECT carrier_id, carrier_name, active FROM vicidial_carriers;
-- Check SIP carrier details
SELECT * FROM vicidial_sip_headers WHERE carrier_id = 'YOUR_CARRIER' \G
-- Update carrier settings (e.g., increase timeout)
UPDATE vicidial_carriers
SET notes = 'Timeout 45s, Qualify enabled'
WHERE carrier_id = 'YOUR_CARRIER';
-- Check if there are carrier-specific SIP parameters
SELECT * FROM vicidial_sip_headers LIMIT 10;
Verify ViciDial Dialplan Integration
ViciDial's dialplan in /etc/asterisk/extensions-vicidial.conf must properly route to carriers:
grep -n "from-carrier\|from-external" /etc/asterisk/extensions-vicidial.conf | head -20
# Should show proper routing contexts for incoming calls from carrier
Check the ViciDial web admin panel for carrier configuration:
- Navigate to
/vicidial/admin.php - Go to Carriers section
- Edit your SIP carrier
- Verify:
- Carrier IP/Host: Correct
- Carrier Port: Usually 5060
- Protocol: SIP UDP or TCP
- DID Pattern: Matches your incoming numbers
- Active: Yes
Real-World Troubleshooting Scenarios
Scenario 1: Intermittent Timeouts Under Load
Symptom: Timeouts happen when call volume is high, not during testing.
Root Cause: Network congestion or Asterisk overload causing response delays.
Solution:
# Check Asterisk CPU and memory under load
top -p $(pgrep asterisk)
# Check network interface statistics
netstat -i
# Monitor packet loss
mtr -r -c 100 203.0.113.50 | tail -5
# If packet loss > 2%, contact carrier or ISP
# If Asterisk CPU > 80%, increase server resources or reduce call load
Increase SIP timeouts further:
[general]
sip_invite_timeout = 60
max_retries = 10
Scenario 2: International Carrier Timeouts
Symptom: Timeouts to UK, India, or other remote carriers, but domestic calls work fine.
Root Cause: High latency on international routes (normal 100-300ms).
Solution:
# Measure latency to carrier
ping -c 20 sip.international-carrier.com | grep -E 'min/avg/max'
# Example output: min/avg/max = 150.234/175.123/200.456 ms
# With this latency, set sip_t1 to ~200-250ms
Configure for international:
[international_carrier]
type = peer
host = sip.international-carrier.com
sip_t1 = 250 ; Match latency
sip_invite_timeout = 60 ; Very tolerant
max_retries = 10
qualify = yes
qualify_timeout = 5
Scenario 3: DNS Resolution Failures
Symptom: Carrier works sometimes, then stops. Logs show "unresolved"
Root Cause: Carrier hostname not resolving, or DNS is failing intermittently.
Solution:
# Check Asterisk's DNS resolution
nslookup sip.carrier.com
dig sip.carrier.com
# Force Asterisk to use specific nameserver in /etc/asterisk/asterisk.conf:
# [options]
# Don't add this to asterisk.conf typically, instead use system resolver
# Check /etc/resolv.conf
cat /etc/resolv.conf
# Add reliable nameservers (Google DNS, Cloudflare DNS)
# Edit /etc/resolv.conf or netplan config
# For Ubuntu 20.04+ (Netplan):
nano /etc/netplan/00-installer-config.yaml
# Add:
# nameservers:
# addresses: [8.8.8.8, 8.8.4.4, 1.1.1.1]
netplan apply
# Verify:
nslookup sip.carrier.com
Use carrier IP directly instead of hostname (if stable):
[carrier]
type = peer
host = 203.0.113.50 ; Use IP instead of hostname
; ... rest of config
Scenario 4: One-Way Audio (RTP Issues)
Symptom: Calls connect (no 408), but no audio. Often misdiagnosed as timeout.
Root Cause: RTP ports blocked or NAT misconfiguration.
Solution:
# Ensure RTP port range is open
grep "rtpstart\|rtpend" /etc/asterisk/rtp.conf
# Should show something like:
# rtpstart=10000
# rtpend=20000
# Verify firewall allows RTP
iptables -L -n -v | grep "10000:20000"
# If not present, add:
iptables -I INPUT -p udp --dport 10000:20000 -j ACCEPT
iptables -I OUTPUT -p udp --dport 10000:20000 -j ACCEPT
# For carrier-specific NAT, ensure externip includes RTP:
# In sip.conf: externip = YOUR_PUBLIC_IP (applies to all media)
Verify RTP is actually flowing:
# Tcpdump on RTP port range during call
tcpdump -i any -n 'udp portrange 10000-20000' -c 50
Monitoring and Alerting
Set Up Asterisk Logging for SIP Issues
Configure detailed SIP logging:
# Edit logger configuration
nano /etc/asterisk/logger.conf
# Add these lines:
[logfiles]
sip => WARNING,NOTICE,DEBUG
messages => WARNING,NOTICE,ERROR
# Optionally log to separate file:
# messages => WARNING,NOTICE,ERROR(/var/log/asterisk/sip-debug.log)
Reload logging:
asterisk -rx "logger reload"
# Tail the debug log
tail -f /var/log/asterisk/messages | grep -i "sip\|timeout"
Monitor 408 Errors in ViciDial Logs
# Check ViciDial call logs for 408 patterns
mysql -u root -p asterisk << 'EOF'
SELECT call_date, vicidial_id, length_in_sec, hangup_cause
FROM vicidial_log
WHERE hangup_cause LIKE '%408%' OR hangup_cause LIKE '%timeout%'
AND call_date >= DATE_SUB(NOW(), INTERVAL 1 DAY)
LIMIT 20;
EOF
# Check closer log (agent-initiated calls)
mysql -u root -p asterisk << 'EOF'
SELECT call_date, closer_id, length_in_sec, hangup_reason
FROM vicidial_closer_log
WHERE hangup_reason LIKE '%timeout%'
AND call_date >= DATE_SUB(NOW(), INTERVAL 24 HOUR);
EOF
Create a Real-Time Monitoring Script
#!/bin/bash
# File: /usr/local/bin/monitor-sip-408.sh
CARRIER_IP="203.0.113.50"
ALERT_EMAIL="[email protected]"
THRESHOLD=10 # Alert if 10+ timeouts in 5 minutes
while true; do
# Count recent 408s from tcpdump (5 minute window)
TIMEOUT_COUNT=$(timeout 10 tcpdump -i any -n "host $CARRIER_IP and port 5060" -A 2>/dev/null | \
grep -c "SIP/2.0 408")
if [ "$TIMEOUT_COUNT" -gt "$THRESHOLD" ]; then
echo "ALERT: $TIMEOUT_COUNT SIP 408 timeouts detected" | \
mail -s "ViciDial SIP 408 Alert" "$ALERT_EMAIL"
# Log to asterisk messages
asterisk -rx "log channel verbose \"ALERT: High 408 timeout rate detected: $TIMEOUT_COUNT\""
fi
sleep 300 # Check every 5 minutes
done
Make it executable and add to cron:
chmod +x /usr/local/bin/monitor-sip-408.sh
# Add to crontab
(crontab -l 2>/dev/null; echo "@reboot /usr/local/bin/monitor-sip-408.sh &") | crontab -
Troubleshooting Checklist
Use this systematic approach when 408 errors occur:
#!/bin/bash
# ViciDial SIP 408 Diagnostic Checklist
echo "=== SIP 408 Troubleshooting Checklist ==="
echo ""
# 1. Network Connectivity
echo "[1] Testing carrier connectivity..."
CARRIER_IP="203.0.113.50"
timeout 5 bash -c "echo > /dev/tcp/$CARRIER_IP/5060" && echo "✓ Port 5060 accessible" || echo "✗ Port 5060 blocked"
# 2. Asterisk Binding
echo "[2] Checking Asterisk SIP bindings..."
netstat -tlnp 2>/dev/null | grep asterisk | grep 5060 && echo "✓ Asterisk listening on 5060" || echo "✗ Asterisk not bound to 5060"
# 3. Firewall Rules
echo "[3] Verifying firewall rules..."
iptables -L -n 2>/dev/null | grep -q "5060" && echo "✓ Firewall rules exist" || echo "✗ No firewall rules found"
# 4. RTP Configuration
echo "[4] Checking RTP port range..."
grep -E "rtpstart|rtpend" /etc/asterisk/rtp.conf && echo "✓ RTP configured" || echo "✗ RTP config missing"
# 5. NAT Configuration
echo "[5] Verifying NAT settings..."
grep "externip\|nat" /etc/asterisk/sip-vicidial.conf | head -3
# 6. Timeout Values
echo "[6] SIP timeout settings..."
grep -E "sip_invite_timeout|sip_t1|max_retries" /etc/asterisk/sip-vicidial.conf | head -5
# 7. Active Channels
echo "[7] Current SIP channels..."
asterisk -rx "sip show channels" 2>/dev/null | head -10
# 8. Carrier Status
echo "[8] Carrier registration status..."
asterisk -rx "sip show peers" 2>/dev/null | grep -i carrier
# 9. Recent Errors
echo "[9] Recent SIP errors in logs..."
tail -20 /var/log/asterisk/messages | grep -i "408\|timeout\|sip"
echo ""
echo "=== End Diagnostic ==="
Save as /usr/local/bin/check-sip-408.sh and run:
chmod +x /usr/local/bin/check-sip-408.sh
./check-sip-408.sh
Summary
SIP 408 Request Timeout errors in ViciDial are almost always caused by one of these factors:
Firewall/NAT Issues (most common): Ensure inbound SIP/RTP from carrier is explicitly allowed, and externip is correctly set.
Aggressive Timeouts: Increase
sip_invite_timeoutto 30-60 seconds andsip_t1to 500-1000ms for production stability.Network Path Problems: Verify latency with
ping/mtr, usetcpdumpto confirm packets reach Asterisk.Carrier Configuration: Double-check carrier IP, port, and context routing in both
/etc/asterisk/sip-vicidial.confand ViciDial database.DNS Failures: Use carrier IPs directly if hostname resolution is unreliable.
Quick Fix Procedure:
- Run
/usr/local/bin/check-sip-408.shto identify the issue - If firewall: Add rules with
iptablesorufw - If timeouts: Update
/etc/asterisk/sip-vicidial.confwith carrier-specific settings - If NAT: Verify
externipmatches your public IP - Reload SIP:
asterisk -rx "sip reload" - Test with
tcpdumpto confirm fix - Monitor logs:
tail -f /var/log/asterisk/messages
Most 408 issues resolve within 30 minutes using this systematic approach. Document your carrier-specific settings for future reference, and implement monitoring to catch issues before users report them.