Asterisk

Asterisk Voicemail: Configuration, Email Delivery and Common Failures

Himanshu Pal

Himanshu Pal

How voicemail is organised

Voicemail lives in voicemail.conf, and its structure trips people up because it has an extra layer they do not expect: mailboxes live inside voicemail contexts, which are unrelated to dialplan contexts despite the shared name.

A mailbox is therefore identified by number and context, written with an at-sign: 6001@default. Referring to a mailbox as just 6001 works only when the default context is implied, and getting this wrong is the most common voicemail fault there is.

[general]
format = wav49|gsm|wav
attach = yes
maxmsg = 25
maxsecs = 180
maxsilence = 5
skipms = 3000

[default]
6001 => 1234,Jane Smith,jane@example.com
6002 => 1234,Ravi Patel,ravi@example.com

The mailbox line reads: password, then owner name, then email address. That password is what the user types to collect messages — set it to something other than the default and make users change it, because voicemail systems with default PINs are a real attack surface.

The settings worth tuning

  • maxmsg — maximum messages retained per mailbox. Without a sensible limit, disused mailboxes accumulate indefinitely.
  • maxsecs — maximum length of a single message in seconds. Around 180 is generous; without it, a caller who never hangs up records until something else stops them.
  • attach — whether the recording is attached to the notification email.
  • format — which formats messages are stored in. Note the interaction: whatever you attach to email must be in the list, so if you want WAV attachments, WAV must be a stored format.

The VoiceMail application

Sending a caller to voicemail from the dialplan:

exten => 6001,1,Dial(PJSIP/6001,20)
 same => n,VoiceMail(6001@default,u)
 same => n,Hangup()

The option letters after the mailbox control which greeting plays. The three you will use:

  • u — play the unavailable message. Use this after a ring timeout.
  • b — play the busy message. Use this when the extension is engaged.
  • s — skip the system-generated instructions, going straight to the beep.

Choosing between u and b based on why the call failed is a small touch that makes a system feel considered:

exten => 6001,1,Dial(PJSIP/6001,20)
 same => n,Goto(${DIALSTATUS})
 same => n(BUSY),VoiceMail(6001@default,b)
 same => n(NOANSWER),VoiceMail(6001@default,u)
 same => n,Hangup()

Users collect their messages through VoiceMailMain():

exten => *97,1,VoiceMailMain(${CALLERID(num)}@default)

Passing the caller's own extension means they are not asked which mailbox they want — a small convenience that users notice.

Voicemail to email

This is the feature everyone wants and the one that most often fails, because it depends on the server's mail configuration rather than on Asterisk.

Enable attachment and set an address per mailbox, then customise the notification with emailbody, which overrides the default text and supports variable substitution:

[general]
attach = yes
serveremail = pbx@example.com
emailsubject = New voicemail from ${VM_CIDNAME}
emailbody = Hello ${VM_NAME},\n\nYou received a ${VM_DUR} message from ${VM_CIDNAME} (${VM_CIDNUM}) on ${VM_DATE}.\n\nMessage ${VM_MSGNUM} in mailbox ${VM_MAILBOX}.

The available variables include ${VM_NAME}, ${VM_DUR}, ${VM_MSGNUM}, ${VM_MAILBOX}, ${VM_CIDNAME}, ${VM_CIDNUM} and ${VM_DATE}. Putting the caller's number in the subject line is worth doing — it makes the notification useful on a phone lock screen without opening anything.

When email does not arrive

Asterisk hands the message to the local mail transfer agent and considers its job done. Almost every failure is downstream of that:

  • No MTA configured. Asterisk needs a working local mailer. Test independently before blaming Asterisk.
  • Mail rejected as spam. A PBX sending mail from a residential or cloud IP with no SPF record is textbook spam. Relay through a real mail service and set SPF and DKIM.
  • Attachment missing. Check that attach = yes is set and that the attachment format is one of the stored formats.
  • Sender address rejected. Set serveremail to an address the relay is permitted to send as.

Prove where the failure is by testing the mail path directly from the server. If a plain mail command does not deliver, no amount of voicemail configuration will.

Why messages land in the wrong mailbox

Nearly always the context. VoiceMail(6001) and VoiceMail(6001@default) are not interchangeable once you have more than one voicemail context, and "couldn't find mailbox" errors almost always mean the context is missing or misspelled.

Check what Asterisk believes exists:

asterisk -rx "voicemail show users"
asterisk -rx "voicemail show zones"

The second matters for timestamps. Voicemail zones control the timezone and date format used in notifications, and a mailbox with no zone gets the server's timezone — which for a cloud-hosted PBX is often UTC. Users reading "received at 03:14" for a mid-afternoon call reasonably conclude the system is broken.

Message waiting indication

MWI is what lights the lamp on a desk phone. It requires the phone to subscribe to the mailbox and the endpoint configuration to reference the right one. In PJSIP:

[6001]
type=endpoint
mailboxes=6001@default

If the lamp never lights, confirm that string exactly matches the mailbox including its context, and that the phone is actually subscribing — a missing subscription is invisible until you look at a trace.

Frequently asked questions

Why does Asterisk say it cannot find the mailbox?

The voicemail context is missing or wrong. Mailboxes are identified as number@context, and voicemail contexts are separate from dialplan contexts despite the shared terminology.

Why is voicemail-to-email not arriving?

Nearly always the mail path, not Asterisk. Confirm a working MTA, check spam filtering, and set SPF and DKIM if you are sending from a cloud IP.

What is the difference between the u and b options?

u plays the unavailable greeting, b plays the busy greeting. Branch on DIALSTATUS to choose the right one.

Why are voicemail timestamps wrong?

The mailbox has no voicemail zone, so it inherits the server timezone — commonly UTC on a hosted server. Define a zone and assign it.