Master the complete diagnostic and resolution process for SIP 403 Forbidden errors affecting your ViciDial trunks and Asterisk SIP authentication
Overview
A SIP 403 Forbidden error indicates that your Asterisk server attempted to authenticate with a remote SIP trunk provider, but the credentials or authorization rules were rejected. In ViciDial production environments, this manifests as failed outbound calls, dropped inbound routes, and frustrated agents seeing "trunk unavailable" errors.
This tutorial covers the exact troubleshooting methodology used in production ViciDial deployments running hundreds of concurrent calls. You'll learn to diagnose root causes, modify configurations, validate changes, and implement monitoring to prevent future occurrences.
Prerequisites
- Active ViciDial installation (16.x or later)
- Root or sudo access to your Asterisk server
- Familiarity with Linux command line and basic Asterisk concepts
- Access to
/etc/asterisk/configuration directory - ViciDial MySQL database credentials
- SIP trunk provider account details and authentication parameters
- Working Asterisk CLI access via
asterisk -rxcommands
Understanding SIP 403 Forbidden in Context
What Causes 403 Forbidden Errors
A 403 Forbidden response in SIP means the upstream server understood your request but refused to authorize it. Unlike 401 (Unauthorized, requiring credentials) or 407 (Proxy Authentication Required), a 403 indicates:
- Invalid or expired credentials
- Username/password mismatch
- IP authentication failure
- Rate limiting or blacklisting
- Missing or incorrect authentication headers
- Codec mismatch (rarely, but possible)
- Subscriber not authorized for that endpoint
- Account suspension or payment issues
Where ViciDial Processes Trunk Authentication
ViciDial manages trunks through:
- SIP Configuration Files:
/etc/asterisk/sip-vicidial.confcontains peer definitions - Database:
vicidial_carrier_logand trunk definitions in Asterisk dialplan - Extensions Dialplan:
/etc/asterisk/extensions-vicidial.confroutes calls through specific trunks - Asterisk Core: Processes authentication before sending requests upstream
ViciDial Trunk Configuration Structure
Database Trunk Definition
First, verify your trunk exists in the database:
SELECT * FROM vicidial_list WHERE list_id = 'YOUR_TRUNK_ID'\G
For carrier-level configuration, check:
SELECT carrier_id, carrier_name, auth_type, carrier_user, carrier_pass, ip_address FROM vicidial_carrier_log ORDER BY date_added DESC LIMIT 10;
SIP Peer Configuration
Locate your trunk definition in /etc/asterisk/sip-vicidial.conf:
[mytrunksip]
type=peer
host=sip.provider.com
port=5060
username=youraccountname
secret=yourpassword
fromuser=youraccountname
fromdomain=sip.provider.com
context=from-trunk
insecure=port,invite
qualify=yes
qualifyfreq=60
canreinvite=no
dtmfmode=rfc2833
nat=force_rport,comedia
directmedia=no
Key fields related to 403 errors:
username: The authentication username (must match provider account)secret: The password (must match provider configuration exactly)fromuser: The From: header username in outbound requestsfromdomain: The domain used in From: headerhost: The upstream provider's SIP server addressinsecure: Whether to accept requests without authentication verification
Step 1: Locate and Review SIP Trunk Logs
Enable SIP Debug Logging
First, enable full SIP debugging to capture the actual 403 response:
asterisk -rx "sip set debug on"
Generate a test call and watch the console output in real-time:
tail -f /var/log/asterisk/messages | grep -i "sip\|forbidden\|auth"
Capture Full SIP Trace
For detailed analysis, use tcpdump to capture the raw SIP messages:
sudo tcpdump -i any -s 0 -w /tmp/sip_trace.pcap \
'host sip.provider.com and port 5060'
Run a test call, then stop the capture (Ctrl+C).
Convert to readable format:
sudo tshark -r /tmp/sip_trace.pcap -Y sip -O sip > /tmp/sip_trace.txt
Review the trace for the exact 403 response:
grep -A 5 -B 5 "403\|Forbidden" /tmp/sip_trace.txt
Asterisk Verbose Logging
Enable Asterisk verbose mode to log SIP transactions:
asterisk -rx "core set verbose 10"
This produces output in /var/log/asterisk/messages. Monitor during test calls:
tail -100 /var/log/asterisk/messages | grep -E "INVITE|SIP/2.0 403|Trying|Calling"
Step 2: Validate Credentials Against Provider
Verify Provider-Supplied Values
Contact your SIP trunk provider and confirm:
- Account Username: Case-sensitive, no spaces
- Password/Secret: Exactly as configured in their system
- Outbound Proxy/Host: SIP server address and port
- Your IP Address(es): Whitelisted on their system
- DID/Extension: Authorized for your account
- Authentication Method: Digest, Basic, or IP-based
Example request to provider:
"We're receiving 403 Forbidden errors from sip.provider.com when authenticating with username 'accountname'. Can you confirm: (1) the exact password configured for this account, (2) whether IP whitelisting is enabled, (3) what our outbound IP should be, (4) the correct SIP URI format for requests?"
Test With SIPp (SIP Protocol Tester)
Use the sipp tool to test authentication independently:
sudo apt-get install sipp
Create a test scenario file /tmp/test_sip.xml:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<scenario name="Basic SIP UAC">
<send retrans="500">
<![CDATA[
INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: <sip:[email protected]>;tag=[call_number]
To: <sip:[email protected]>
Call-ID: [call_id]
CSeq: 1 INVITE
Contact: <sip:[local_ip]:[local_port]>
Max-Forwards: 70
User-Agent: Test SIPp
Content-Length: 0
]]>
</send>
<recv response="403" />
</scenario>
Run the test:
sipp -sf /tmp/test_sip.xml -s sip.provider.com -p 5060 -ap youraccountname:yourpassword your_local_ip
This tests basic SIP authentication without Asterisk complexity.
Step 3: Check Credential Configuration in ViciDial
Review SIP Configuration File
Open your trunk definition:
grep -A 20 "\[mytrunksip\]" /etc/asterisk/sip-vicidial.conf
Look for:
username=youraccountname
secret=yourpassword
Common mistakes:
- Extra spaces around
=sign - Trailing whitespace on password line
- Password contains special characters not properly escaped
- Wrong username or password copied from wrong provider account
Verify From: Header Construction
The From: header must match provider expectations:
fromuser=youraccountname
fromdomain=sip.provider.com
This constructs: From: "youraccountname" <sip:[email protected]>
Provider may require:
- Your assigned DID as fromuser
- Your domain instead of fromdomain
- A specific format like
[email protected]
Check Extensions Dialplan
Verify your trunk is invoked correctly in /etc/asterisk/extensions-vicidial.conf:
exten => _9XXXXXXXX,1,Dial(SIP/${EXTEN:1}@mytrunksip)
exten => _9XXXXXXXX,n,Hangup()
The @mytrunksip reference must match your peer definition exactly (case-sensitive).
Step 4: Diagnose IP and Network Issues
Verify Outbound IP Address
Your Asterisk server's outbound IP must match what the provider has whitelisted:
curl -s https://api.ipify.org
Or from within Asterisk:
asterisk -rx "sip show settings" | grep "Bindaddr"
Compare this IP against your provider's whitelist.
Test Network Connectivity
Verify basic connectivity to the SIP server:
ping -c 3 sip.provider.com
Test port-level connectivity:
nc -zv sip.provider.com 5060
Check if firewall rules permit SIP traffic:
sudo iptables -L -n | grep 5060
For proper SIP NAT traversal, ensure:
[mytrunksip]
nat=force_rport,comedia
directmedia=no
Verify DNS Resolution
Confirm the provider's hostname resolves correctly:
nslookup sip.provider.com
dig sip.provider.com @8.8.8.8
DNS issues can cause timeouts that look like authentication failures.
Step 5: Resolve Common 403 Scenarios
Scenario A: Credential Mismatch
Symptom: 403 response immediately upon sending INVITE.
Resolution:
- Request fresh credentials from provider
- Update both
usernameandsecretfields:
sudo vi /etc/asterisk/sip-vicidial.conf
- If password contains special characters, escape properly:
secret="pa$$w0rd@2024!"
- Reload SIP configuration:
asterisk -rx "sip reload"
- Test a call and monitor logs:
asterisk -rx "sip set debug on"
# Make test call
asterisk -rx "sip set debug off"
Scenario B: IP Whitelisting
Symptom: 403 error after successful authentication attempts, only from specific network.
Resolution:
- Confirm your public IP:
wget -qO- https://checkip.amazonaws.com
- Contact provider to whitelist this IP
- If using failover/redundancy, whitelist all potential outbound IPs
- Test after provider confirms whitelist update:
asterisk -rx "sip qualify mytrunksip"
Scenario C: Rate Limiting/Blacklisting
Symptom: 403 after initial successful calls, becomes persistent.
Resolution:
- Contact provider to check if your IP is temporarily blocked
- Check for malformed SIP requests in your logs:
grep "malformed\|invalid\|error" /var/log/asterisk/messages | tail -20
- Ensure no SIP scanning attacks from your server:
netstat -tupan | grep 5060
- If provider has rate limits, implement call queuing in ViciDial dialplan to space out requests
Scenario D: Account Suspension/Expiration
Symptom: Abrupt 403 errors with no configuration changes.
Resolution:
- Log into provider's web portal
- Check account status, payment status, and service activation
- Verify DID/trunk subscription is current
- Request manual account re-activation
- Once confirmed active, reload SIP:
asterisk -rx "sip reload"
Scenario E: Inbound Route Mismatch
Symptom: 403 only occurs on inbound calls; outbound works fine.
Resolution:
Inbound calls use different SIP URI matching. Check your inbound context in /etc/asterisk/extensions-vicidial.conf:
[from-trunk]
exten => 5551234567,1,Verbose("Inbound from ${CALLERID(num)}")
exten => 5551234567,n,Dial(Local/5551234567@default)
exten => 5551234567,n,Hangup()
Ensure:
- The inbound DID is exactly what the provider sends (with or without +1 prefix)
- The extension is properly defined in the context
- No invalid characters in the DID
Step 6: Test the Fix
Manual SIP Test Call
Use Asterisk's dial command directly:
asterisk -rx "channel originate SIP/5551234567@mytrunksip Application VoiceMAil"
Monitor the response in real-time:
tail -f /var/log/asterisk/messages | grep -E "INVITE|403|200 OK|Call"
A successful INVITE shows 200 OK response.
Agent Test Call from ViciDial
Log into the ViciDial agent screen at /agc/vicidial.php:
- Log in with test agent account
- Select a campaign with your fixed trunk
- Dial a test number (external cell phone or test service)
- Monitor the call completion
Check call logs in the database:
SELECT call_id, caller_id_number, dialed_number, call_status,
length_in_sec, call_date FROM vicidial_log
WHERE dialed_number = '5551234567'
ORDER BY call_date DESC LIMIT 5;
Look for call_status = 'COMPLETE' or similar success indicators.
Verify SIP Qualify Status
Check if the trunk qualifies (can reach the provider):
asterisk -rx "sip show peers" | grep mytrunksip
Output should show:
mytrunksip/sip.provider.com sip.provider.com:5060 OK
If showing UNREACHABLE, the trunk cannot reach the provider at all. This may indicate network issues or wrong host address.
Advanced Troubleshooting
Parse Raw SIP Headers
If you have a tcpdump capture, extract the exact failing INVITE:
sudo tshark -r /tmp/sip_trace.pcap -Y "sip.Request.Method == INVITE" \
-T fields -e sip.From -e sip.To -e sip.Contact -e sip.User-Agent
Compare the From:/To:/Contact: headers against provider requirements.
Check Asterisk SIP Registry
If your trunk uses outbound registration:
asterisk -rx "sip show registry"
Output shows registration status. Registered means the trunk successfully authenticated with the provider for inbound calls.
If Request Sent or Unregistered, the trunk cannot register:
asterisk -rx "sip set debug on"
asterisk -rx "sip register mytrunksip"
Review Authentication Digest Headers
In tcpdump analysis, look for the response to your INVITE. If it's a 407 (Proxy Authentication Required) followed by your 403 response, your credentials are wrong.
The sequence should be:
- INVITE (no auth) → 407 Proxy Auth Required
- ACK
- INVITE (with Authorization header) → 200 OK or 180 Ringing
If the second INVITE still returns 403, credentials are incorrect.
Extract the Authorization header from tcpdump:
tshark -r /tmp/sip_trace.pcap -Y "sip" -T fields -e sip.Authorization
Compare the username in the Authorization header against your configured username.
Preventive Measures and Monitoring
Monitor for 403 Errors Proactively
Create a monitoring script in /usr/local/bin/check_sip_403.sh:
#!/bin/bash
LOG_FILE="/var/log/asterisk/messages"
THRESHOLD=5
# Count 403 errors in last hour
COUNT=$(grep "SIP/2.0 403" $LOG_FILE | \
awk -v d="$(date -d '1 hour ago' '+%b %d %H')" \
'$0 ~ d' | wc -l)
if [ $COUNT -gt $THRESHOLD ]; then
echo "ALERT: $COUNT SIP 403 errors detected in last hour"
# Send email, page, etc.
# mail -s "ViciDial SIP 403 Alert" [email protected]
exit 1
fi
exit 0
Make executable and add to crontab:
sudo chmod +x /usr/local/bin/check_sip_403.sh
*/5 * * * * /usr/local/bin/check_sip_403.sh
Document Trunk Configuration
Maintain a reference document with:
Trunk Name: mytrunksip
Provider: Provider Name
Host: sip.provider.com:5060
Username: accountname (NOT case-sensitive at provider)
Password: (hash, not plaintext) - updated DATE
From Domain: sip.provider.com
Outbound IPs: 203.0.113.45
Inbound DIDs: 555-123-4567, 555-123-4568
Support Contact: +1-555-0000
Rate Limits: 100 CPS
Last Verified: DATE
Known Issues: None
Implement Health Checks
Add to your monitoring system (Nagios, Zabbix, etc.):
check_sip_qualify() {
local trunk=$1
asterisk -rx "sip show peers" | grep -q "$trunk.*OK"
}
check_sip_qualify mytrunksip && echo "OK" || echo "CRITICAL"
Log Rotation Configuration
Ensure Asterisk logs don't fill disk, which can mask 403 errors. Check /etc/logrotate.d/asterisk:
/var/log/asterisk/messages {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 0640 asterisk asterisk
postrotate
/usr/sbin/asterisk -rx "logger rotate" > /dev/null 2>&1 || true
endscript
}
Troubleshooting Decision Tree
Is the trunk showing in "sip show peers"?
├─ NO → Check sip-vicidial.conf syntax and reload
├─ YES → Does "sip show registry" show it registered?
├─ NO (401 or 407) → Credentials are wrong
├─ YES → Are you seeing 403 on INVITE only?
├─ YES → IP whitelist or rate limit issue
└─ NO → Check From: header format
Common ViciDial-Specific Issues
Issue: Multiple Trunks, One Returns 403
ViciDial may route calls through the wrong trunk. Check extensions-vicidial.conf:
exten => _9XXXXXXXX,1,Dial(SIP/${EXTEN:1}@mytrunksip)
If this extension pattern is ambiguous, other patterns might match first. Use more specific patterns:
exten => _91NXXXXXX,1,Dial(SIP/${EXTEN:1}@mytrunksip)
exten => _9011.,1,Dial(SIP/${EXTEN:1}@intl_trunk)
Issue: Campaign Trunk Assignment
In ViciDial, verify campaign uses the correct trunk in database:
SELECT campaign_id, campaign_name, vtiger_id FROM vicidial_campaigns
WHERE campaign_id = 'TESTCAMP';
SELECT trunk_id, carrier_id FROM vicidial_campaign_carriers
WHERE campaign_id = 'TESTCAMP';
Wrong trunk assignment will route calls through a trunk with bad credentials.
Issue: Lead Filtering by Trunk
Check if leads are filtered to specific trunks in vicidial_list:
SELECT list_id, carrier_id, count(*) FROM vicidial_list
WHERE carrier_id IS NOT NULL
GROUP BY list_id, carrier_id;
If a list requires a specific trunk with 403 errors, leads cannot be called.
Summary
SIP 403 Forbidden errors in ViciDial require systematic diagnosis:
- Enable debugging to see the actual error in context
- Validate credentials match provider configuration exactly
- Verify networking allows packets to reach the provider
- Check IP whitelisting with your provider
- Test independently using sipp before restarting Asterisk
- Monitor proactively with log analysis and SIP qualify checks
- Document everything for future troubleshooting
The most common causes are wrong credentials, IP whitelisting issues, and provider account problems. Always contact your SIP provider with specific details:
"SIP 403 Forbidden error from [your outbound IP] to [their SIP host] with username [username] at [specific time]. Can you check authentication logs?"
Keep Asterisk SIP logging enabled in production (sip set debug on in verbosity levels), rotate logs regularly, and set up alerts for repeated 403 errors. This prevents lost calls and identifies problems before they impact your operation.