Setting Up Voicemail in Asterisk

Getting Started Asterisk 18+ -- Last reviewed 2026-08-22 voicemail pjsip getting-started mwi email Found this useful? Upvote it. ×

Setting Up Voicemail in Asterisk

VoicemailAsterisk's built-in voice messaging system (app_voicemail), configured in voicemail.conf with mailboxes per user. is one of the first things people ask about after getting phones to ring. Two applications do the work: VoiceMail() records messages, and VoiceMailMain() lets users listen to them. Configuration lives in voicemail.conf.

On this page

A minimal voicemail.conf

Back up your configuration files

Before editing any Asterisk configuration file, make a backup copy: bash sudo cp /etc/asterisk/voicemail.conf /etc/asterisk/voicemail.conf.bak.$(date +%s) If a typo prevents Asterisk from reloading, you can restore the working version immediately.

Open /etc/asterisk/voicemail.conf and start with this:

[general]
format = wav
serveremail = asterisk@yourdomain.com
attach = yes
mailcmd = /usr/sbin/sendmail -t
maxmsg = 100
maxsecs = 180
minsecs = 3
maxsilence = 0
silencethreshold = 128
maxgreet = 60
minpassword = 6

[zonemessages]
eastern = America/New_York|'vm-received' Q 'digits/at' IMp
central = America/Chicago|'vm-received' Q 'digits/at' IMp
pacific = America/Los_Angeles|'vm-received' Q 'digits/at' IMp

[default]
200 => 739182,Desk Phone,user@example.com,,tz=eastern
201 => 825406,Softphone,user2@example.com,,tz=eastern

The [general] section controls global behavior. The [zonemessages] section defines how timestamps are read back to users. The [default] section is where mailboxes live.

Each mailbox line follows this format:

extension => password,name,email,pager,options

The password is a numeric PIN because VoiceMailMain() reads DTMFDual-Tone Multi-Frequency, the touch-tone signals phones send for digit input during a call, used by IVRs and feature codes. digits from the phone keypad. Use unique, nontrivial PINs and enforce an appropriate minimum with minpassword. The email address receives notifications when new messages arrive, after mail delivery is configured on the server.

This baseline disables silence detection with maxsilence = 0. If you enable it, maxsilence must be lower than minsecs, or Asterisk warns that empty messages may be stored. Test the value with real callers because a short silence timeout can end a thoughtful caller's message. See Voicemail maxsilence Must Be Less Than minsecs for details.

format = wav stores one copy of each message and is suitable for most deployments. Add another format only when you have a specific playback or attachment requirement. Do not change the format list after mailboxes contain messages unless you also convert, add, or remove each stored message file to match. Upstream warns that an unreconciled format change can disrupt message retrieval and management.

Applying the changes

After editing voicemail.conf, load the new mailboxes:

asterisk -rx "voicemail reload"

After editing extensions.conf or an included dialplanThe core call-routing configuration of Asterisk, written mostly in extensions.conf as contexts, extensions, and priorities that decide how every call is handled. Full definition → file, load the new dialplanThe core call-routing configuration of Asterisk, written mostly in extensions.conf as contexts, extensions, and priorities that decide how every call is handled. Full definition →:

asterisk -rx "dialplan reload"

If you change PJSIPThe modern SIP channel driver in Asterisk (chan_pjsip), replacing the older chan_sip. Configured in pjsip.conf using endpoints, AORs, auths, and transports. endpointIn PJSIP configuration, the SIP entity Asterisk communicates with: a phone, trunk, or other user agent. Defined by an endpoint section in pjsip.conf. or AoR settings such as mailboxes, reload PJSIP as shown in the MWI section.

Connecting voicemail to the dialplan

The typical dialplan pattern rings the phone, then sends unanswered or unavailable calls to voicemail.

[internal]
exten => 200,1,Dial(PJSIP/200,25)
same => n,GotoIf($["${DIALSTATUS}" = "NOANSWER"]?vm)
same => n,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL"]?vm)
same => n,Hangup()
same => n(vm),VoiceMail(200@default,u)
same => n,Hangup()

VoiceMail(200@default,u) records a message in mailbox 200 in the [default] contextA named section of the dialplan that groups extensions. Calls enter a specific context and can only reach extensions visible from it, making contexts the basic unit of call routing and security.. The u flag plays the unavailable greeting.

The CHANUNAVAIL check is important. When a phone is not registered or reachable, Dial() sets DIALSTATUS to CHANUNAVAIL, not NOANSWER. Without that check, callers get a hangup instead of voicemail whenever the phone is offline.

To use a busy greeting for a busy line, handle all three cases:

exten => 200,1,Dial(PJSIP/200,25)
same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy)
same => n,GotoIf($["${DIALSTATUS}" = "NOANSWER"]?unavail)
same => n,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL"]?unavail)
same => n,Hangup()
same => n(unavail),VoiceMail(200@default,u)
same => n,Hangup()
same => n(busy),VoiceMail(200@default,b)
same => n,Hangup()

Letting users check their messages

VoiceMailMain() handles listening, saving, deleting, greeting changes, and password changes.

[internal]
; Dial *98 to check the caller's mailbox
exten => *98,1,VoiceMailMain(${CALLERID(num)}@default)
same => n,Hangup()

; Dial *97 to choose a mailbox
exten => *97,1,VoiceMailMain(@default)
same => n,Hangup()

The first version fills the mailbox from caller IDThe calling party number (and optionally name) presented on an outbound call, set from the endpoint or manipulated in the dialplan., so extensionA dialplan entry that matches a dialed number or pattern within a context and triggers a sequence of prioritized steps. 200 calling *98 only needs the PIN. The second prompts for a mailbox number first, which is useful from shared phones.

Message waiting indicators

MWI is the light or visual indicator that reports new voicemail. PJSIP supports two common models.

For unsolicited MWI, configure mailboxes on the endpoint. Asterisk sends NOTIFY messages when the mailbox state changes:

[200]
type = endpoint
context = internal
mailboxes = 200@default

For solicited MWI, where the phone sends a SIPSession Initiation Protocol, the standard signaling protocol used to set up, manage, and tear down VoIP calls between Asterisk and phones or carriers. SUBSCRIBE request, associate the mailbox with the endpoint's AoR instead:

[200]
type = aor
max_contacts = 1
mailboxes = 200@default

Use the model supported by your phone and provisioning setup. If you configure both, review mwi_subscribe_replaces_unsolicited so subscribed notifications do not produce surprising behavior.

Reload PJSIP after changes:

asterisk -rx "pjsip reload"

If the light does not work, confirm that the value is exactly mailbox@context, that the option is on the correct PJSIP object for your MWI model, and that MWI is enabled on the phone.

Email notifications

With attach = yes and an email address on the mailbox, Asterisk sends a notification with the recording attached. Asterisk normally invokes a sendmail-compatible command through mailcmd, commonly /usr/sbin/sendmail -t. Postfix, Exim, Sendmail, or an msmtp sendmail wrapper can provide that interface, depending on your operating system.

First verify that the configured executable exists:

test -x /usr/sbin/sendmail && echo "sendmail interface found"

Then leave an actual voicemail. That tests Asterisk's message generation, attachment, configured mailcmd, and outbound delivery together. Check the Asterisk log and your mail transport log if the message does not arrive. Common mail log locations include /var/log/mail.log and the system journal.

A separate mail command can be a useful transport smoke test, but it requires a mail client package and does not prove that Asterisk's configured command works. See Voicemail with Email Notification for a fuller setup.

You can delete a voicemail from the server after Asterisk hands off its notification:

[default]
200 => 739182,Desk Phone,user@example.com,,tz=eastern|delete=yes

Use delete=yes only after end-to-end testing

This option is intended for users who receive voicemail only by email. The server copy is removed after notification, so a delivery failure, filtering rule, or lost attachment may leave no retrievable voicemail in VoiceMailMain(). Verify delivery, retention, backups, and failure monitoring before enabling it.

Voicemail contexts

The [default] context is just a name. Each context is an independent group of mailboxes with its own numbering space.

Why use multiple contexts

Two tenants can both use extension 100 when their mailboxes are in separate contexts:

[tenant-a]
100 => 510093,Reception A,reception@tenant-a.com,,tz=eastern
101 => 510184,Sales A,sales@tenant-a.com,,tz=eastern

[tenant-b]
100 => 620095,Reception B,reception@tenant-b.com,,tz=pacific
101 => 620186,Sales B,sales@tenant-b.com,,tz=pacific

VoiceMail(100@tenant-a,u) and VoiceMail(100@tenant-b,u) are separate mailboxes with separate greetings, PINs, and message stores.

Departmental separation

Contexts can also separate departments:

[sales]
300 => 731905,Alice,alice@company.com,,tz=eastern
301 => 731806,Bob,bob@company.com,,tz=eastern

[support]
400 => 842907,Carol,carol@company.com,,tz=eastern
401 => 842608,Dave,dave@company.com,,tz=eastern

The dialplan routes to the correct context:

[internal]
exten => _3XX,1,Dial(PJSIP/${EXTEN},25)
same => n,GotoIf($["${DIALSTATUS}" = "NOANSWER"]?vm)
same => n,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL"]?vm)
same => n,Hangup()
same => n(vm),VoiceMail(${EXTEN}@sales,u)
same => n,Hangup()

exten => _4XX,1,Dial(PJSIP/${EXTEN},25)
same => n,GotoIf($["${DIALSTATUS}" = "NOANSWER"]?vm)
same => n,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL"]?vm)
same => n,Hangup()
same => n(vm),VoiceMail(${EXTEN}@support,u)
same => n,Hangup()

Give each department an unambiguous feature code for checking messages:

exten => *91,1,VoiceMailMain(${CALLERID(num)}@sales)
same => n,Hangup()

exten => *92,1,VoiceMailMain(${CALLERID(num)}@support)
same => n,Hangup()

Using a single feature code hardcoded to one context would fail for users whose mailboxes are in another context.

MWI with non-default contexts

The PJSIP mailboxes value must include the matching context:

[300]
type = endpoint
context = internal
mailboxes = 300@sales

The format is always mailbox@context for app_voicemail mailboxes.

Recording custom greetings

The normal way to record greetings is through VoiceMailMain(). Dial the mailbox access extension, log in, choose mailbox options, then record the unavailable, busy, or name greeting offered by the menu. Menu numbers can differ with prompts and configuration, so follow the prompts on the installed system.

The CLI command below only lists configured users. It does not record greetings:

asterisk -rx "voicemail show users"

For filesystem-backed voicemail, recordings are typically stored under /var/spool/asterisk/voicemail/<context>/<mailbox>/. Examples include unavail.wav and busy.wav. If an administrator provisions these files outside VoiceMailMain(), create audio in a format Asterisk can read and preserve the ownership and permissions used by the Asterisk service.

Password policy and storage

minpassword = 6 rejects shorter PIN changes, but length alone does not catch repeated or predictable values. Use externpasscheck when you need an external policy script to validate a proposed PIN. Prefixing a mailbox password with - makes it unchangeable, which is useful only when another system owns the credential and has a safe reset process.

By default, Asterisk reads and writes mailbox PINs in voicemail.conf. With passwordlocation = spooldir, it stores each changed PIN in secret.conf inside the mailbox spool directory. That value is plain text. Restrict access to both the configuration and spool directories, and include the chosen password location in backup and restore procedures.

Common problems

"No such voicemail context" means the context in VoiceMail(200@default) does not match a section in voicemail.conf, or a mailbox was referenced without its required context.

Messages record but email never arrives. Confirm mailcmd, leave a real voicemail, and inspect the Asterisk and mail transport logs. A successful mail client test alone does not verify Asterisk's sendmail-compatible command.

MWI light stays off. Match mailbox@context exactly. Put mailboxes on the endpoint for unsolicited NOTIFY messages or on the AoR for phone-initiated subscriptions, then confirm that the phone supports the selected model.

maxsilence cuts off messages too early. Set it to 0 to disable silence detection, or tune it with real calls. When enabled, it must remain lower than minsecs. Raising it above minsecs is not a valid fix.

Password rejected. Check minpassword and any externpasscheck script. A changed PIN may be in voicemail.conf or in the mailbox's secret.conf, depending on passwordlocation. Reload voicemail after an administrator changes the active source.

Phone offline, caller gets a hangup instead of voicemail. Check for both NOANSWER and CHANUNAVAIL after Dial(), as shown above.

Sources

A solid choice for hosting Asterisk.

High-performance cloud compute starting at $2.50/mo. Deploy a VPS in seconds.

Get $100 Free Credit

Referral link. Helps support this site.

User Notes

Know a tip or gotcha for this topic? Share it below and help others.

Contribute a note

Share a tip, gotcha, or practical example. Keep it under 2000 characters. No questions (use the Asterisk community forums for support). Wrap code in backticks.

Moderated before publishing. Email never shown.
Related Snippets