Macro to Gosub Migration

Getting Started -- Last reviewed 2026-08-02 dialplan gosub macro migration asterisk-21 Found this useful? Upvote it. ×

Macro to Gosub Migration

Old Asterisk dialplans often use Macro() for reusable call logic. New dialplans should use Gosub() instead. Gosub() is clearer, nests correctly, returns explicitly, and is the supported pattern after app_macro was removed in Asterisk 21. Asterisk 20 and older releases may still load it, but it is deprecated and should be migrated.

Macro pattern

A classic macro might look like this:

[macro-dial-user]
exten => s,1,NoOp(Dialing ${ARG1})
 same => n,Dial(PJSIP/${ARG1},20)
 same => n,MacroExit()

[internal]
exten => _1XX,1,Macro(dial-user,${EXTEN})
 same => n,Hangup()

Inside a macro, arguments are exposed as ${ARG1}, ${ARG2}, and so on. The macro always starts at s,1 in a context named macro-name.

Gosub equivalent

[sub-dial-user]
exten => s,1,NoOp(Dialing ${ARG1})
 same => n,Dial(PJSIP/${ARG1},20)
 same => n,Return()

[internal]
exten => _1XX,1,Gosub(sub-dial-user,s,1(${EXTEN}))
 same => n,Hangup()

The arguments still appear as ${ARG1}, ${ARG2}, and so on. The difference is that the destination is explicit: context, extension, priority, and optional argument list.

Migration rules

Macro Gosub
Macro(name,arg1,arg2) Gosub(sub-name,s,1(arg1,arg2))
[macro-name] [sub-name] or another normal context name
MacroExit() Return()
${MACRO_EXTEN} Pass ${EXTEN} as an argument when needed
${MACRO_CONTEXT} Pass ${CONTEXT} as an argument when needed
${MACRO_PRIORITY} Pass priority only if the subroutine really needs it

Before and after example

; Before
[macro-record-and-dial]
exten => s,1,MixMonitor(${UNIQUEID}.wav)
 same => n,Dial(PJSIP/${ARG1},${ARG2})
 same => n,MacroExit()

[internal]
exten => _1XX,1,Macro(record-and-dial,${EXTEN},25)
 same => n,Hangup()

; After
[sub-record-and-dial]
exten => s,1,MixMonitor(${UNIQUEID}.wav)
 same => n,Dial(PJSIP/${ARG1},${ARG2})
 same => n,Return()

[internal]
exten => _1XX,1,Gosub(sub-record-and-dial,s,1(${EXTEN},25))
 same => n,Hangup()

Common mistakes

See Also

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