Freeze the restored target and one failing path
Record timestamp and timezone, source and target FreePBX and Asterisk versions, backup identity and hash, restore transaction, installed modules, custom-file inventory, Apply Config result, failing number or route, expected destination, actual result, channel identifiers and the first CLI or log error. Keep the restored target isolated from production registration and PSTN routing.
Classify the first mismatch as file absent, include absent, generated configuration not reloaded, Macro application unavailable, stale Custom Destination, missing context or priority, wrong argument, variable-scope change, missing Return, stack imbalance, wrong channel, unexpected hangup or downstream route failure.
Prove that the custom source and include were restored
Compare the archive manifest and restore log with the target path, ownership and content hash. Confirm the supported custom include is actually referenced by the loaded configuration and that Apply Config completed after the source was placed. A file on disk is not evidence that Asterisk parsed or loaded it.
If the file is missing, stop at the archive, module handler, path or restore boundary. Do not recreate remembered dialplan from production traffic or widen filesystem permissions until the owning backup component and expected destination are known.
Locate every obsolete Macro dependency
Search the loaded and source custom dialplan plus AGI code for Macro-family calls and macro- contexts. On the FreePBX 17/Asterisk 22 default described by Sangoma, an unavailable Macro application is an engine compatibility failure, not a trunk or endpoint problem. Preserve the exact line and caller before converting it.
Do not stop after replacing the first Macro() token. Inventory MacroIf, MacroExit, exclusivity, offsets and MACRO_CONTEXT, MACRO_EXTEN or MACRO_PRIORITY use, because each represents a control-flow or state contract that plain Gosub syntax does not recreate automatically.
Trace the Gosub frame, arguments and variable scope
Confirm the caller names an existing context, extension and priority, arguments are inside parentheses, and execution reaches the intended frame on the intended channel. Capture ARG1 onward, reviewed LOCAL() values and any explicitly passed original extension or context.
If a value disappears after Return(), determine whether it was deliberately local. If a nested routine sees the wrong value, record frame depth before using LOCAL_PEEK(). Do not convert all variables to inherited channel state merely to make one branch pass; that can leak stale values into sibling or later call legs.
Prove exactly how the routine exits
Follow every branch to Return(value), a deliberate Goto, hangup or another terminal application. A missing Return() can run into unrelated priorities or leave the caller without its expected continuation. An extra Return or StackPop can remove the wrong frame. Compare the observed return priority and GOSUB_RETVAL with the documented caller contract.
Keep the separate existing Asterisk Gosub diagnostic for generic wrong-channel or stack behavior. Here, first prove whether the symptom begins at the FreePBX restore and Macro-removal boundary before treating it as a new subroutine defect.
Correct one boundary and run a safe acceptance matrix
Correct only the first proven owner: restore content, include, Apply Config, Custom Destination, obsolete Macro call, Gosub target, argument mapping, local scope, exit branch or downstream destination. Repeat the failing route and a known-good control on the isolated target, then test every documented branch and rollback.
A clean CLI trace is not proof of caller experience, media or production interoperability. Record final routing and only reconnect trunks after the normal migration acceptance and change-control gates. No PBX, backup, restore, file, dialplan, AGI script, channel, route or call was inspected or tested for this diagnostic.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- Sangoma: upgrading to FreePBX 17 ↗
- Sangoma: FreePBX 17 platform overview ↗
- Asterisk 20 Macro application reference ↗
- Asterisk Gosub application reference ↗
- Asterisk Gosub subroutine guide ↗
- Asterisk Return application reference ↗
- Asterisk LOCAL function reference ↗
- Asterisk LOCAL_PEEK function reference ↗
- Asterisk StackPop application reference ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.