Migrating Vicidial Carriers from chan_sip to PJSIP

By Connectivity King

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.10 and 203.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 -V and 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_sip binds via bindport in /etc/asterisk/sip.conf.
  • PJSIP binds via the bind line 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 aors and, for registration trunks, pjsip show registrations (look for Registered).
  • 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:

  1. Outbound: the call connects, audio flows both ways, and the far end sees the correct caller ID.
  2. Inbound: ask the carrier to send a test call, then confirm it arrives on KINGPJ and routes to the right in-group.
  3. DTMF: press digits into an IVR on both legs.
  4. 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:

  1. Change the production 9 pattern so it dials PJSIP/${EXTEN:1}@KINGPJ, or move campaigns to the new prefix. Either works; just stay consistent.
  2. Set the old KINGTRUNK carrier to Active: N. Don't delete it yet.
  3. 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 identify object. Add a match= line for every source IP.
  • Nothing registers after the restart: the two stacks are fighting over a port. Re-check bindport and the transport bind.
  • 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. Align allow= 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.

Request a Quote →

Put the King to work

Enjoyed the read? Tell us about your call center and we’ll put together a quote.

Request a quote
Connectivity King mascot, a crowned VoIP phone answering a call