Learn to configure production-grade voicemail in Asterisk with email notifications, custom greetings, transcription, and IVR routing for ViciDial environments.
Prerequisites
Before starting this tutorial, ensure you have:
- Asterisk 13.x or higher installed and running (ViciDial typically runs 11.x through 16.x)
- Root or sudo access to your Asterisk server
- MySQL/MariaDB with an existing Asterisk database (vicidial user with appropriate permissions)
- Postfix or Exim mail server configured and tested
- sox and mailx utilities installed for audio handling and mail delivery
- Asterisk source code downloaded (for custom modules if needed)
- ViciDial version 2.12+ (if integrating with ViciDial's agent interface)
- Working SIP extensions or IAX2 trunks configured
- Basic understanding of Asterisk dialplan syntax and Linux command line
Verify Asterisk is running:
sudo asterisk -rx "core show version"
sudo systemctl status asterisk
Understanding Asterisk Voicemail Architecture
Asterisk voicemail operates through the app_voicemail module, which stores voicemail messages in the filesystem (typically /var/spool/asterisk/voicemail/) and maintains metadata in Asterisk's astdb or via ODBC connectivity.
The complete voicemail flow:
- Call arrives → matches voicemail extension in dialplan
- Answer and greeting → plays custom or default greeting
- Record message → stores to filesystem with timestamp
- Notification → triggers email dispatch via MTA
- Retrieval → agent retrieves via
*98or IVR menu - Archive → system moves old messages or deletes per policy
In ViciDial environments, voicemail ties directly to the vicidial_users table and can be correlated with vicidial_log entries for compliance and reporting.
Section 1: Core Voicemail Configuration
Installing and Enabling app_voicemail
Verify app_voicemail is compiled:
sudo asterisk -rx "module show like voicemail"
If not loaded:
sudo asterisk -rx "module load app_voicemail"
To make it persistent across restarts, edit /etc/asterisk/modules.conf:
[modules]
autoload=yes
; Specific voicemail module
load => app_voicemail.so
load => res_adsi.so
load => res_smdi.so
Creating the Voicemail Context
Edit /etc/asterisk/voicemail.conf to define voicemail boxes and contexts:
[general]
; Format for storing voicemail
format=wav49|gsm|wav
; Maximum message length in seconds (600 = 10 minutes)
maxmessage=600
minmessage=3
; Silence threshold (in milliseconds)
silencethreshold=128
; Number of seconds of silence to end message
maxsilence=10
; Email notification settings
[email protected]
fromstring=ViciDial Voicemail
emaildateformat=%A, %B %d, %Y at %l:%M %p
attachvolumeenvelope=yes
attach=yes
; Envelope format and headers
emailsubject=You have a voicemail message from ${VM_CALLERID}
emailbody=Dear ${VM_NAME},\n\nYou have received a new voicemail message from ${VM_CALLERID}.\n\nMessage length: ${VM_DUR} seconds\nReceived: ${VM_DATE}\n\nPlease retrieve your message at your earliest convenience.\n\nViciDial Team
[vicidial_context]
; Mailbox format: mailbox=>password,fullname,email,pager_email,options
; Options include: u(unavail), b(busy), t(tempgreeting), g(greeting)
6001=>9999,Agent Smith,[email protected],,uj(voicemail-inactive)
6002=>8888,Agent Jones,[email protected],,uj(voicemail-inactive)
6003=>7777,Agent Brown,[email protected],,u
; Bulk add for 100 users (6100-6199)
6100=>1111,Sales Agent 100,[email protected]
6101=>1111,Sales Agent 101,[email protected]
The format breakdown:
mailbox= voicemail extension (typically matches SIP extension)password= digit code to access voicemailfullname= announced name for callersemail= primary notification recipientpager_email= secondary recipient (often mobile)options= flags for unavailable (u), busy (b), temporary greeting (t), greeting recorded (g)
Linking ViciDial Users to Voicemail
ViciDial's vicidial_users table has voicemail integration points. Query the schema:
SHOW COLUMNS FROM vicidial_users LIKE '%voicemail%';
If your ViciDial version supports it, you'll see fields like voicemail_ext or vm_enabled. Alternatively, create a mapping table:
CREATE TABLE IF NOT EXISTS vicidial_voicemail_map (
user_id INT NOT NULL PRIMARY KEY,
vm_ext VARCHAR(10),
vm_password VARCHAR(10),
vm_email VARCHAR(100),
vm_enabled ENUM('Y','N') DEFAULT 'Y',
INDEX idx_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Populate it:
INSERT INTO vicidial_voicemail_map (user_id, vm_ext, vm_password, vm_email, vm_enabled)
SELECT user_id, extension, '9999', email, 'Y'
FROM vicidial_users
WHERE user_status='ACTIVE' AND role='AGENT';
Section 2: Dialplan Integration & IVR Routing
Creating the Voicemail Dialplan Context
Edit /etc/asterisk/extensions-vicidial.conf and add a dedicated voicemail context:
[voicemail-context]
; Main voicemail entry point
exten => s,1,Verbose(2,Entering voicemail context from ${CALLERID(num)})
exten => s,n,Set(VM_CONTEXT=vicidial_context)
exten => s,n,Playback(vm-welcome,noanswer)
exten => s,n,VoiceMail(${EXTEN}@${VM_CONTEXT},u)
exten => s,n,Hangup()
; Voicemail menu for agents (*98 access)
[voicemail-main-menu]
exten => s,1,NoOp(Voicemail Main Menu for ${CALLERID(num)})
exten => s,n,Set(ATTEMPT=0)
exten => s,n(authenticate)
exten => s,n,Set(ATTEMPT=$[${ATTEMPT} + 1])
exten => s,n,Playback(vm-login,noanswer)
exten => s,n,Read(VMBOX,vm-enter-id,5)
exten => s,n,Read(VMPASS,vm-enter-password,5)
exten => s,n,VoiceMailMain(${VMBOX}@${VM_CONTEXT})
exten => s,n,Hangup()
; Access voicemail directly with extension
exten => _610[0-9],1,NoOp(Direct voicemail for ${EXTEN})
exten => _610[0-9],n,VoiceMail(${EXTEN}@vicidial_context,u)
exten => _610[0-9],n,Hangup()
; Fallback for invalid extensions
exten => i,1,Playback(invalid,noanswer)
exten => i,n,Hangup()
IVR-Based Voicemail Routing
For more sophisticated call routing, create an IVR menu that directs calls to agent voicemail or live queue:
[vicidial-ivr-main]
exten => s,1,NoOp(=== ViciDial IVR Entry ===)
exten => s,n,Set(CHANNEL(language)=en)
exten => s,n,Playback(vm-goodbye,noanswer)
exten => s,n(menu)
exten => s,n,Playback(press-1-for-sales,noanswer)
exten => s,n,Playback(press-2-for-support,noanswer)
exten => s,n,Playback(press-0-operator,noanswer)
exten => s,n,WaitExten(5)
exten => 1,1,NoOp(=== Sales Queue ===)
exten => 1,n,Queue(sales_queue,t,,,300)
exten => 1,n,VoiceMail(6100@vicidial_context,u)
exten => 1,n,Hangup()
exten => 2,1,NoOp(=== Support Queue ===)
exten => 2,n,Queue(support_queue,t,,,300)
exten => 2,n,VoiceMail(6200@vicidial_context,u)
exten => 2,n,Hangup()
exten => 0,1,NoOp(=== Operator Transfer ===)
exten => 0,n,Dial(SIP/6001,20)
exten => 0,n,VoiceMail(6001@vicidial_context,b)
exten => 0,n,Hangup()
exten => t,1,Playback(vm-goodbye,noanswer)
exten => t,n,Hangup()
exten => i,1,Playback(invalid,noanswer)
exten => i,n,Goto(s,menu)
Assign this context to your inbound trunk in sip.conf or SIP configuration:
[my_carrier_trunk]
type=peer
context=vicidial-ivr-main
host=carrier.example.com
insecure=invite
Section 3: Email Integration & Notifications
Configuring Postfix for Voicemail Delivery
Ensure Postfix is installed and running:
sudo apt-get install postfix mailutils
sudo systemctl start postfix
sudo systemctl enable postfix
Test mail delivery:
echo "Test message" | mail -s "Test" [email protected]
Advanced Voicemail Email Configuration
Update /etc/asterisk/voicemail.conf with full email settings:
[general]
; Email delivery
[email protected]
fromstring=ViciDial Voicemail System
emaildateformat=%A, %B %d, %Y at %l:%M %p
; Attach voicemail as audio file
attach=yes
attachvolumeenvelope=yes
; Audio formats to attach (most compatible first)
format=wav49|gsm|wav
; Email body templates
emailsubject=Voicemail: ${VM_CALLERID} - ${VM_DATE}
emailbody=Dear ${VM_NAME},\n\nYou have a voicemail message.\n\nCaller: ${VM_CALLERID}\nLength: ${VM_DUR} seconds\nReceived: ${VM_DATE}\nBox: ${VM_MAILBOX}\n\nTo retrieve: Dial *98 and enter your voicemail password.\n\nViciDial System
; Pager/SMS format (text-only)
pagerfromstring=ViciDial Alerts
pagersubject=VM from ${VM_CALLERID}
pagerbody=${VM_NAME}, new voicemail from ${VM_CALLERID} (${VM_DUR}s) at ${VM_DATE}
; Maximum email size (prevent bloat)
volgain=0
emaildateformat=%A, %B %d, %Y at %l:%M %p
[vicidial_context]
; Per-mailbox override
6001=>9999,Agent Smith,[email protected],[email protected],uj
6002=>8888,Agent Jones,[email protected],,u
Custom Email Handler Script
For advanced processing (transcription, CRM integration), create /usr/local/bin/voicemail-handler.sh:
#!/bin/bash
# ViciDial Voicemail Handler Script
# Called by Asterisk after voicemail recording
VMBOX="$1"
CONTEXT="$2"
MAILBOX_DIR="/var/spool/asterisk/voicemail/${CONTEXT}/${VMBOX}"
CALLERID="$3"
DURATION="$4"
# Logging
LOG_FILE="/var/log/asterisk/voicemail-handler.log"
echo "$(date '+%Y-%m-%d %H:%M:%S') - Processing VM: Box=$VMBOX, Caller=$CALLERID, Duration=$DURATION" >> "$LOG_FILE"
# Get most recent message
LATEST_MSG=$(ls -t "$MAILBOX_DIR/new/"*.wav 2>/dev/null | head -1)
if [ -z "$LATEST_MSG" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: No message found for $VMBOX" >> "$LOG_FILE"
exit 1
fi
# Convert to MP3 (optional, requires sox)
if command -v sox &> /dev/null; then
MP3_FILE="${LATEST_MSG%.wav}.mp3"
sox "$LATEST_MSG" -C 128 "$MP3_FILE" 2>> "$LOG_FILE"
ATTACH_FILE="$MP3_FILE"
else
ATTACH_FILE="$LATEST_MSG"
fi
# Query ViciDial database for mailbox owner info
AGENT_EMAIL=$(mysql -u asterisk -pasterisk asterisk -N -e \
"SELECT email FROM vicidial_users WHERE extension='$VMBOX' LIMIT 1;" 2>/dev/null)
if [ -z "$AGENT_EMAIL" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - WARNING: No email found for extension $VMBOX" >> "$LOG_FILE"
exit 1
fi
# Send email with attachment
MAIL_SUBJECT="Voicemail from $CALLERID (${DURATION}s)"
MAIL_BODY="You have a new voicemail message.\n\nCaller: $CALLERID\nDuration: ${DURATION} seconds\nReceived: $(date '+%Y-%m-%d %H:%M:%S')\n\nPlease see attached audio file."
echo -e "$MAIL_BODY" | mutt -s "$MAIL_SUBJECT" -a "$ATTACH_FILE" -- "$AGENT_EMAIL" 2>> "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') - Email sent to $AGENT_EMAIL" >> "$LOG_FILE"
exit 0
Make it executable and update Asterisk to call it:
sudo chmod +x /usr/local/bin/voicemail-handler.sh
Register in voicemail.conf (requires custom module compilation for some versions):
[general]
; Call external script after voicemail saved
; Note: This requires res_voicemail compiled with SENDMAIL support
mailcmd=/usr/local/bin/voicemail-handler.sh
ODBC-Based Voicemail Storage (Alternative)
For high-volume environments, store voicemail metadata in MySQL instead of astdb:
Create the table:
CREATE TABLE asterisk.voicemail_msgs (
id INT AUTO_INCREMENT PRIMARY KEY,
context VARCHAR(50),
mailbox VARCHAR(50),
callerid VARCHAR(50),
duration INT,
message_date DATETIME,
is_read ENUM('Y','N') DEFAULT 'N',
INDEX idx_context_mailbox (context, mailbox),
INDEX idx_date (message_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Configure ODBC in /etc/asterisk/res_odbc.conf:
[asterisk]
dsn=asterisk
username=asterisk
password=asterisk
pooling=yes
limit=10
Update voicemail.conf to use ODBC:
[general]
; Enable ODBC support
odbcstorage=asterisk
odbctable=voicemail_msgs
Section 4: Agent Retrieval Interface
Enabling *98 Voicemail Access
Add to your main extension context in extensions-vicidial.conf:
[vicidial-agents]
; Agent voicemail retrieval (*98)
exten => 98,1,NoOp(Voicemail retrieval initiated by ${CALLERID(num)})
exten => 98,n,Authenticate(${EXTEN})
exten => 98,n,VoiceMailMain(@vicidial_context)
exten => 98,n,Hangup()
; Record temporary greeting (*99)
exten => 99,1,NoOp(Recording temporary greeting)
exten => 99,n,VoiceMailMain(${CALLERID(num)}@vicidial_context,t)
exten => 99,n,Hangup()
Include this context in your SIP extensions:
[6000-6299](vicidial_agent)
type=friend
context=vicidial-agents
disallow=all
allow=ulaw,gsm
Web-Based Voicemail Retrieval for ViciDial
Add a custom PHP interface at /var/www/html/vicidial/voicemail.php:
<?php
// ViciDial Web Voicemail Interface
session_start();
// Verify agent is logged in
if (!isset($_SESSION['user_id'])) {
header("Location: index.php");
exit;
}
$user_id = $_SESSION['user_id'];
$user_extension = $_SESSION['extension'];
// Database connection
$db = new mysqli("localhost", "asterisk", "asterisk", "asterisk");
if ($db->connect_error) {
die("Database connection failed: " . $db->connect_error);
}
// Retrieve voicemail boxes for user
$query = "SELECT vm_ext, vm_email FROM vicidial_voicemail_map WHERE user_id = ?";
$stmt = $db->prepare($query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$result = $stmt->get_result();
?>
<!DOCTYPE html>
<html>
<head>
<title>Voicemail Manager</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.vm-box { border: 1px solid #ccc; padding: 10px; margin: 10px 0; }
.controls { margin: 10px 0; }
button { padding: 8px 15px; cursor: pointer; }
</style>
</head>
<body>
<h2>Voicemail Manager</h2>
<?php
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
?>
<div class="vm-box">
<h3>Extension <?php echo htmlspecialchars($row['vm_ext']); ?></h3>
<p>Email: <?php echo htmlspecialchars($row['vm_email']); ?></p>
<div class="controls">
<button onclick="accessVoicemail('<?php echo $row['vm_ext']; ?>')">
Access Voicemail
</button>
<button onclick="recordGreeting('<?php echo $row['vm_ext']; ?>')">
Record Greeting
</button>
</div>
</div>
<?php
}
} else {
echo "<p>No voicemail boxes configured for your account.</p>";
}
?>
<script>
function accessVoicemail(ext) {
// Trigger Asterisk originate call to VoiceMailMain
fetch('voicemail-api.php', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'action=access&ext=' + encodeURIComponent(ext)
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('Voicemail dialing to ' + ext);
} else {
alert('Error: ' + data.message);
}
});
}
function recordGreeting(ext) {
if (confirm('Record temporary greeting for ' + ext + '?')) {
fetch('voicemail-api.php', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'action=greeting&ext=' + encodeURIComponent(ext)
})
.then(response => response.json())
.then(data => {
alert(data.message);
});
}
}
</script>
</body>
</html>
Backend API at /var/www/html/vicidial/voicemail-api.php:
<?php
// Voicemail API for originating calls
session_start();
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['success' => false, 'message' => 'Unauthorized']);
exit;
}
$action = $_POST['action'] ?? '';
$ext = preg_replace('/[^0-9]/', '', $_POST['ext'] ?? '');
if (empty($ext)) {
echo json_encode(['success' => false, 'message' => 'Invalid extension']);
exit;
}
// Use Asterisk Manager Interface or AGI to originate call
$user_ext = $_SESSION['extension'];
$priority = ($action === 'greeting') ? 't' : 'u';
// Option 1: Use Asterisk Manager (requires AMI configuration)
$socket = fsockopen('localhost', 5038, $errno, $errstr, 2);
if (!$socket) {
echo json_encode(['success' => false, 'message' => 'Cannot connect to Asterisk']);
exit;
}
fwrite($socket, "Action: Login\r\nUsername: admin\r\nSecret: your_ami_secret\r\n\r\n");
fgets($socket, 1024);
$cmd = "Action: Originate\r\n"
. "Channel: SIP/$user_ext\r\n"
. "Context: vicidial-agents\r\n"
. "Exten: $ext\r\n"
. "Priority: 1\r\n"
. "Async: true\r\n\r\n";
fwrite($socket, $cmd);
$response = fgets($socket, 1024);
fwrite($socket, "Action: Logoff\r\n\r\n");
fclose($socket);
echo json_encode(['success' => true, 'message' => 'Voicemail access initiated']);
Section 5: Advanced Features
Voicemail Transcription
Integrate with Google Cloud Speech-to-Text or Voicemail Transcription service:
#!/bin/bash
# /usr/local/bin/transcribe-voicemail.sh
VM_FILE="$1"
OUTPUT_FILE="${VM_FILE%.wav}.txt"
# Convert WAV to FLAC (Google requires)
flac "$VM_FILE" -o "${VM_FILE%.wav}.flac"
# Send to Google Speech-to-Text API
curl -X POST \
--data-binary @"${VM_FILE%.wav}.flac" \
-H "Content-Type: audio/flac" \
"https://www.google.com/speech-api/json?output=json&client=chromium&key=YOUR_API_KEY" \
> "$OUTPUT_FILE"
# Extract text from response
TRANSCRIPT=$(python3 -c "
import json
import sys
with open('$OUTPUT_FILE') as f:
data = json.load(f)
if 'result' in data and len(data['result']) > 0:
print(data['result'][0]['alternative'][0]['transcript'])
" 2>/dev/null)
# Update database with transcript
mysql -u asterisk -pasterisk asterisk -e \
"INSERT INTO voicemail_transcripts (vm_file, transcript, created_date) \
VALUES ('$VM_FILE', '$TRANSCRIPT', NOW());"
echo "Transcription complete: $TRANSCRIPT"
Voicemail Purging & Archival
Create a maintenance script at /usr/local/bin/voicemail-maintenance.sh:
#!/bin/bash
# Archive and delete old voicemail messages
VOICEMAIL_ROOT="/var/spool/asterisk/voicemail"
ARCHIVE_DIR="/backup/voicemail-archive"
RETENTION_DAYS=90
# Create archive directory
mkdir -p "$ARCHIVE_DIR"
# Find and archive messages older than 90 days
find "$VOICEMAIL_ROOT" -type f -name "*.wav" -mtime +$RETENTION_DAYS | while read file; do
dir=$(dirname "$file")
context=$(basename $(dirname "$dir"))
mailbox=$(basename "$dir")
# Create archive structure
archive_path="$ARCHIVE_DIR/$context/$mailbox"
mkdir -p "$archive_path"
# Move file to archive
mv "$file" "$archive_path/"
# Also move metadata
base=$(basename "$file" .wav)
[ -f "$dir/$base.txt" ] && mv "$dir/$base.txt" "$archive_path/"
[ -f "$dir/$base.gsm" ] && mv "$dir/$base.gsm" "$archive_path/"
echo "$(date) - Archived: $file"
done
# Tar and compress old archives (>30 days old)
find "$ARCHIVE_DIR" -type f -mtime +30 | xargs tar -czf "$ARCHIVE_DIR/voicemail-$(date +%Y%m%d).tar.gz"
echo "Voicemail maintenance completed at $(date)"
Schedule in crontab:
0 2 * * * /usr/local/bin/voicemail-maintenance.sh >> /var/log/voicemail-maintenance.log 2>&1
Voicemail Analytics & Reporting
Query voicemail activity:
-- Voicemail message count per agent
SELECT
vl.user_id,
vu.user_name,
vu.extension,
COUNT(*) as vm_count,
AVG(vl.message_length) as avg_duration,
MAX(vl.call_date) as last_voicemail
FROM vicidial_log vl
JOIN vicidial_users vu ON vl.user_id = vu.user_id
WHERE vl.disposition = 'VOICEMAIL'
GROUP BY vl.user_id
ORDER BY vm_count DESC;
-- Voicemail response time (how long until agent retrieves)
SELECT
mailbox,
COUNT(*) as total_voicemails,
AVG(TIMESTAMPDIFF(HOUR, created, accessed)) as avg_retrieval_hours
FROM voicemail_msgs
WHERE accessed IS NOT NULL
GROUP BY mailbox;
Section 6: Troubleshooting
Voicemail Not Recording
Symptom: Calls go to voicemail but no message is left.
Diagnosis:
# Check voicemail module is loaded
sudo asterisk -rx "module show like voicemail"
# Check dialplan is correct
sudo asterisk -rx "dialplan show voicemail-context"
# Check filesystem permissions
ls -la /var/spool/asterisk/voicemail/
sudo chown -R asterisk:asterisk /var/spool/asterisk/voicemail/
sudo chmod -R 755 /var/spool/asterisk/voicemail/
Solution:
Reload dialplan and modules:
sudo asterisk -rx "dialplan reload"
sudo asterisk -rx "module reload app_voicemail"
Email Notifications Not Sending
Symptom: Voicemails recorded but no email received.
Diagnosis:
# Check mail service
sudo systemctl status postfix
sudo mailq
# Test mail delivery directly
echo "Test" | mail -s "Test Subject" [email protected]
# Check Asterisk logs
tail -f /var/log/asterisk/full
grep -i "voicemail\|email" /var/log/asterisk/full
# Verify voicemail.conf settings
grep -A5 "serveremail\|attach\|format" /etc/asterisk/voicemail.conf
Solution:
Ensure Postfix is running and configured:
sudo postfix start
# Test SMTP connectivity
telnet localhost 25
Verify voicemail.conf has attach=yes and correct serveremail.
Agent Cannot Access Voicemail via *98
Symptom: Dialing *98 hangs or says extension not found.
Diagnosis:
# Verify extension pattern
sudo asterisk -rx "dialplan show vicidial-agents"
# Check SIP registration
sudo asterisk -rx "sip show peers" | grep 600
# Test with asterisk -vvv
sudo asterisk -vvv
# Then dial *98 and watch console output
Solution:
Ensure voicemail-agents context is included in agent SIP profiles:
[6000-6299](vicidial_agent)
type=friend
context=vicidial-agents
Reload SIP:
sudo asterisk -rx "sip reload"
Voicemail Files Corrupted or Unplayable
Symptom: Voicemail records but plays as noise.
Diagnosis:
# Check file format and integrity
file /var/spool/asterisk/voicemail/vicidial_context/6001/INBOX/*.wav
# Play file manually
sox /var/spool/asterisk/voicemail/vicidial_context/6001/INBOX/msg0000.wav -t raw -
# Check codec mismatch in dialplan
sudo asterisk -rx "core show codecs"
Solution:
Ensure codec configuration matches in sip.conf:
allow=ulaw,gsm,g729
disallow=all
Verify voicemail format in voicemail.conf is compatible:
format=wav49|gsm|ulaw
Performance Issues with Large Voicemail Spool
Symptom: Asterisk slow, voicemail access lags.
Diagnosis:
# Check spool disk usage
du -sh /var/spool/asterisk/voicemail/
# Count total files
find /var/spool/asterisk/voicemail -type f | wc -l
# Check I/O wait
iostat -x 1 5
Solution:
Implement archival maintenance (see Section 5), migrate to ODBC backend, or use external storage:
# Enable S