Migrating Vicidial Carriers from chan_sip to PJSIP
If your Vicidial carriers still run on chan_sip, the clock is ticking. Asterisk deprecated chan_sip in version 17 and removed it entirely in Asterisk 21, and carriers increasingly test their trunks against PJSIP. The good news: Vicidial supports PJSIP carriers, and you can move them one at a time while your floor keeps dialing.
This guide covers a safe, side-by-side migration: enable both stacks, translate your carrier entry, test on a separate dial prefix, then cut campaigns over with a rollback plan. It builds on our step-by-step guide to adding a SIP trunk carrier in Vicidial, so if you've never filled in the carrier form, start there. As before, every IP address, hostname and credential below is a placeholder.
Placeholders used in this guide
- Carrier signaling IPs:
203.0.113.10and203.0.113.11- Carrier hostname:
sip.carrier.example- Your dialer's public IP:
203.0.113.50- Old chan_sip carrier ID:
KINGTRUNK· New PJSIP carrier ID:KINGPJ
Before You Start: Take Inventory
A migration goes wrong when someone forgets what the old setup was quietly doing. Before you touch anything, write down:
- Every active carrier: its Carrier ID, protocol, account entry, globals string and dialplan entry. Copy the text out of the admin screen into a file. That's your rollback.
- How each carrier authenticates: IP authentication or registration.
- Every IP the carrier sends traffic from. chan_sip often accepted inbound calls loosely. PJSIP needs each source IP listed explicitly.
- Which campaigns use which dial prefix, and which inbound DIDs arrive over each carrier.
- Your Asterisk and Vicidial versions (
asterisk -Vand the version shown in the admin). PJSIP carrier support depends on a reasonably current Vicidial build. - A maintenance window outside your calling hours, and someone who can place test calls.
Ask your carrier whether anything changes on their side for PJSIP. Usually nothing does, because the carrier only sees SIP, not your channel driver. But confirm the codecs, DTMF method and number format while you have them.
Step 1: Enable PJSIP Alongside chan_sip
In the Vicidial admin, go to Admin → System Settings and set Allowed SIP Stacks to SIP_and_PJSIP. That lets both stacks coexist across your cluster while you migrate. You'll switch to PJSIP only once everything has moved.
Two stacks can't listen on the same port. Check which one owns 5060:
chan_sipbinds viabindportin/etc/asterisk/sip.conf.- PJSIP binds via the
bindline of the transport in/etc/asterisk/pjsip.conf.
Vicidial's own PJSIP notes describe swapping these so PJSIP takes 5060, and setting external_media_address and external_signaling_address on the PJSIP transport to your public IP (203.0.113.50). Whichever layout you choose, tell your carrier if the port they send inbound traffic to is changing, and update your firewall rules to match. Restart Asterisk after changing transports, during your maintenance window.
Step 2: Translate the Old Peer
Here's a typical IP-authenticated chan_sip account entry, the kind you're migrating away from:
[KINGTRUNK]
type=peer
host=203.0.113.10
insecure=port,invite
context=trunkinbound
disallow=all
allow=ulaw
dtmfmode=rfc2833
canreinvite=no
nat=force_rport,comedia
qualify=yes
PJSIP splits that single peer into separate objects. Most options map directly:
| chan_sip | PJSIP equivalent |
|---|---|
type=peer |
separate endpoint + aor (+ auth for registration) |
host=203.0.113.10 |
contact=sip:203.0.113.10:5060 on the aor |
insecure=port,invite |
an identify object with match= lines |
canreinvite=no |
direct_media=no |
nat=force_rport,comedia |
force_rport=yes, rtp_symmetric=yes, rewrite_contact=yes |
dtmfmode=rfc2833 |
dtmf_mode=rfc4733 |
qualify=yes |
qualify_frequency=30 on the aor |
register => line |
a registration object |
Asterisk ships a conversion script, sip_to_pjsip.py, in its contrib/scripts folder. It's handy for seeing how options translate. But Vicidial carriers live in the admin database, not in a file you edit by hand, so treat its output as a reference and paste the cleaned-up result into the carrier form yourself.
Step 3: Build the New Carrier Side by Side
Don't edit the old carrier. Go to Admin → Carriers → Add A New Carrier, set Carrier ID to KINGPJ, Protocol to PJSIP, choose the Server IP, leave Active at N for now, and paste this Account Entry for IP authentication:
[KINGPJ]
type=aor
contact=sip:203.0.113.10:5060
qualify_frequency=30
[KINGPJ]
type=identify
endpoint=KINGPJ
match=203.0.113.10
match=203.0.113.11
[KINGPJ]
type=endpoint
context=trunkinbound
disallow=all
allow=ulaw
dtmf_mode=rfc4733
direct_media=no
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
send_rpid=yes
trust_id_inbound=yes
aors=KINGPJ
Keep context=trunkinbound. That's where Vicidial expects inbound carrier calls to land, so your DID routing keeps working.
If your carrier uses registration instead, add an auth object and a registration object, and point the endpoint at the credentials:
[KINGPJ-auth]
type=auth
auth_type=userpass
username=YOUR_USERNAME
password=YOUR_PASSWORD
[KINGPJ-reg]
type=registration
outbound_auth=KINGPJ-auth
server_uri=sip:sip.carrier.example
client_uri=sip:YOUR_USERNAME@sip.carrier.example
retry_interval=60
Then add outbound_auth=KINGPJ-auth to the endpoint and set the AOR contact to sip:sip.carrier.example. Some carriers also want from_user or from_domain on the endpoint, so check their documentation.
Step 4: Add a Test Dialplan on a Spare Prefix
Give the new carrier its own dial prefix so it can't touch live campaigns. If your production prefix is 9, use 8 for testing:
exten => _81NXXNXXXXXX,1,AGI(agi://127.0.0.1:4577/call_log)
exten => _81NXXNXXXXXX,n,Dial(PJSIP/${EXTEN:1}@KINGPJ,,To)
exten => _81NXXNXXXXXX,n,Hangup()
Note the syntax change. chan_sip dials SIP/KINGTRUNK/number, while PJSIP dials PJSIP/number@KINGPJ. Get it backwards and Asterisk reports that the endpoint doesn't exist, which looks like a configuration problem but is just a typo. Keep the AGI(...call_log) step first, and keep the o in the Dial options, as with any Vicidial carrier.
Set the carrier to Active: Y and give Vicidial a minute to rebuild the configuration.
Step 5: Test Before Anything Moves
From the Asterisk CLI (asterisk -rvvv):
pjsip show endpoint KINGPJ: the endpoint should exist and show your identify matches.pjsip show aorsand, for registration trunks,pjsip show registrations(look forRegistered).pjsip set logger on: watch the SIP exchange during a test call, then turn it off again.
Create a test campaign (or use a test agent with manual dialing) on prefix 8, with a campaign caller ID you're authorized to use, and check:
- Outbound: the call connects, audio flows both ways, and the far end sees the correct caller ID.
- Inbound: ask the carrier to send a test call, then confirm it arrives on
KINGPJand routes to the right in-group. - DTMF: press digits into an IVR on both legs.
- Hangups: both sides tear the call down cleanly, with no stuck channels.
Step 6: Cut Over, with a Way Back
Once tests pass, move production in the quiet window:
- Change the production
9pattern so it dialsPJSIP/${EXTEN:1}@KINGPJ, or move campaigns to the new prefix. Either works; just stay consistent. - Set the old
KINGTRUNKcarrier to Active: N. Don't delete it yet. - Watch the first live calls on the CLI, and check your dispositions and recordings.
If something goes wrong, rolling back is two clicks: reactivate KINGTRUNK and restore its dialplan. After a few days of clean traffic, delete the old carrier. When every carrier and phone is on PJSIP, set Allowed SIP Stacks to PJSIP. Agent phones are migrated separately, so plan that as its own project.
Common Migration Gotchas
- Inbound calls rejected or unmatched: a carrier IP is missing from the
identifyobject. Add amatch=line for every source IP. - Nothing registers after the restart: the two stacks are fighting over a port. Re-check
bindportand the transportbind. - One-way audio: the external addresses on the PJSIP transport are wrong, or your RTP range is closed to the carrier's media IPs.
488 Not Acceptable Here: codec mismatch. Alignallow=with what the carrier supports.- Duplicate section names: PJSIP is stricter than chan_sip. Every object needs a unique name or a distinct
type, and stray spaces or typos are not forgiven.
Compliance Doesn't Change with the Channel Driver
Moving to PJSIP is plumbing. It doesn't change who you may call or what caller ID you may send. Send only numbers you own or are authorized to use, and keep the TCPA, the Telemarketing Sales Rule, the National Do Not Call Registry, your internal DNC list and state rules front and center: consent, opt-outs, calling hours and abandonment limits are still on you. For how call authentication and labeling actually work, read Does STIR/SHAKEN Stop Spam Labels? This article is general information, not legal advice.
Vicidial PJSIP Migration FAQ
Can chan_sip and PJSIP run at the same time in Vicidial?
Yes. Set Allowed SIP Stacks to SIP_and_PJSIP and make sure each stack listens on its own port. That's what makes a gradual, carrier-by-carrier migration possible.
Do I have to migrate agent phones at the same time?
No. Carriers and phones are configured separately, so you can move carriers first and plan phones later. Existing phones and carriers have to be switched manually.
Is there a tool that converts my chan_sip carrier automatically?
Asterisk includes sip_to_pjsip.py in contrib/scripts. It's a useful reference, but review the output by hand and paste it into the Vicidial carrier form. Vicidial manages carriers from its database.
Why does Asterisk say the endpoint doesn't exist?
Usually it's the dial string. PJSIP uses PJSIP/number@endpoint, not SIP/peer/number. Also check that the endpoint name matches the Carrier ID in your account entry.
Will moving to PJSIP change my STIR/SHAKEN attestation?
No. Attestation is applied by the originating provider based on its relationship with you and your right to use the caller ID, not by your channel driver.
Let the King Handle the Move
Rather not migrate carriers during your own maintenance window? Connectivity King SIP trunks work with Vicidial, GoAutoDial, Asterisk/FreePBX and 3CX, with Tier-1 carrier routes, A-level STIR/SHAKEN attestation on Connectivity King DID numbers and 99.99% network uptime. Our routes, DIDs and porting cover the United States, and call centers based anywhere can sign up. Prefer to skip server work entirely? Our team can build and manage a hosted Vicidial dialer bundled with our VoIP. Weighing it up? Read Hosted Vicidial vs Self-Hosting: What It Really Takes. New to carrier entries? Start with How to Add a SIP Trunk Carrier in Vicidial. Request a quote. Quotes usually come back the same day. You can also reach us at sales@connectivityking.com or +1 (888) 885-4202, Monday to Friday, 9am Eastern to 9pm Pacific.
