Safe Reload with Validation

Administration -- Last reviewed 2026-03-29 administration deployment validation safety Found this useful? Upvote it. ×

Safe Reload with Validation

Never run asterisk -rx "core reload" blind. This script performs basic config file checks, shows a diff of what changed, performs module-specific reloads (checking each for errors), and verifies post-reload health.

Usage

# Validate and reload
sudo ./safe-reload.sh

# Validate only (dry run)
sudo ./safe-reload.sh --check

Script

#!/bin/bash
set -euo pipefail

ASTERISK="/usr/sbin/asterisk"
CONF_DIR="/etc/asterisk"
CHECK_ONLY=false

if [ "${1:-}" = "--check" ]; then
    CHECK_ONLY=true
fi

echo "=== Asterisk Safe Reload ==="
echo ""

# 1. Check that Asterisk is running
if ! ${ASTERISK} -rx "core show version" >/dev/null 2>&1; then
    echo "ERROR: Asterisk is not running or not reachable"
    exit 1
fi

# 2. Check config files for common syntax problems
echo "Checking config file syntax..."
SYNTAX_ERRORS=0
for CONF_FILE in extensions.conf pjsip.conf voicemail.conf queues.conf; do
    if [ ! -f "${CONF_DIR}/${CONF_FILE}" ]; then
        continue
    fi

    # Unclosed section headers: lines starting with [ that don't end with ] or )
    # Handles both [context] and [endpoint](template) forms
    BAD_BRACKETS=$(grep -n '^\[' "${CONF_DIR}/${CONF_FILE}" \
        | grep -v '[])]\s*$' | head -3 || true)
    if [ -n "${BAD_BRACKETS}" ]; then
        echo "  WARNING: Possible unclosed section header in ${CONF_FILE}:"
        echo "${BAD_BRACKETS}" | sed 's/^/    /'
        SYNTAX_ERRORS=$((SYNTAX_ERRORS + 1))
    fi

    # Orphaned extension lines before any context header
    FIRST_CONTEXT=$(grep -n '^\[' "${CONF_DIR}/${CONF_FILE}" | head -1 | cut -d: -f1 || true)
    if [ -n "${FIRST_CONTEXT}" ]; then
        ORPHANS=$(head -n "$((FIRST_CONTEXT - 1))" "${CONF_DIR}/${CONF_FILE}" \
            | grep -n '^exten\s*=>' | head -3 || true)
        if [ -n "${ORPHANS}" ]; then
            echo "  WARNING: Extension lines before first context in ${CONF_FILE}:"
            echo "${ORPHANS}" | sed 's/^/    /'
            SYNTAX_ERRORS=$((SYNTAX_ERRORS + 1))
        fi
    fi
done

if [ "${SYNTAX_ERRORS}" -gt 0 ]; then
    echo "  Found ${SYNTAX_ERRORS} warning(s) -- review before reloading"
else
    echo "  OK: No obvious syntax issues"
fi

# 3. Show current state for comparison
echo ""
echo "Current state:"
ENDPOINT_COUNT=$(${ASTERISK} -rx "pjsip show endpoints" 2>&1 | grep -c "Endpoint:" || true)
echo "  ${ENDPOINT_COUNT} PJSIP endpoints loaded"
EXTENSION_COUNT=$(${ASTERISK} -rx "dialplan show" 2>&1 | tail -1)
echo "  ${EXTENSION_COUNT}"

# 4. Show recent config changes (if git is available)
if command -v git >/dev/null 2>&1 && [ -d "${CONF_DIR}/.git" ]; then
    echo ""
    echo "Recent config changes:"
    (cd "${CONF_DIR}" && git diff --stat HEAD 2>/dev/null | sed 's/^/  /' || true)
    echo ""
fi

if ${CHECK_ONLY}; then
    echo ""
    echo "Dry run complete. No reload performed."
    exit 0
fi

# 5. Module-specific reloads with error checking
echo ""
echo "Reloading modules..."

RELOAD_FAILED=false

for MODULE in "dialplan" "pjsip" "voicemail"; do
    OUTPUT=$(${ASTERISK} -rx "${MODULE} reload" 2>&1 || true)
    if echo "${OUTPUT}" | grep -qi "error\|unable\|failed"; then
        echo "  FAIL: ${MODULE} reload reported errors:"
        echo "${OUTPUT}" | grep -i "error\|unable\|failed" | head -3 | sed 's/^/    /'
        RELOAD_FAILED=true
    else
        echo "  OK: ${MODULE} reloaded"
    fi
done

if ${RELOAD_FAILED}; then
    echo ""
    echo "WARNING: One or more modules reported errors during reload."
    echo "Check the Asterisk CLI for details: asterisk -rvvv"
fi

# 6. Post-reload health check
sleep 2
echo ""
echo "Post-reload verification:"

ACTIVE_CHANNELS=$(${ASTERISK} -rx "core show channels count" 2>&1 | grep "active call" || echo "  0 active calls")
echo "  ${ACTIVE_CHANNELS}"

REG_STATUS=$(${ASTERISK} -rx "pjsip show registrations" 2>&1 | grep -c "Registered" || true)
echo "  ${REG_STATUS} trunk registration(s) active"

NEW_ENDPOINT_COUNT=$(${ASTERISK} -rx "pjsip show endpoints" 2>&1 | grep -c "Endpoint:" || true)
echo "  ${NEW_ENDPOINT_COUNT} PJSIP endpoints loaded (was ${ENDPOINT_COUNT})"

echo ""
echo "Reload complete."

How it works

  1. File-level syntax checks: Scans config files for common structural problems: unclosed section headers (handling both [context] and [endpoint](template) forms) and extension lines that appear before any context header. These checks catch typos that would cause Asterisk to silently ignore config.
  2. Module-specific reloads: Instead of core reload (which reloads everything at once), the script reloads dialplan, pjsip, and voicemail individually and checks each module's output for errors. This makes it clear which module has a problem if something goes wrong.
  3. Git diff integration: If your /etc/asterisk is a git repo (highly recommended), the script shows what files changed since the last commit so you can review before reloading.
  4. Post-reload health check: After reload, verifies Asterisk is still healthy: active channels (existing calls survived), trunk registrations, and endpoint count compared to pre-reload.

Tips

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