caddyserver/caddy · error
preparing 'ask' endpoint: %v
Error message
preparing 'ask' endpoint: %v
What it means
The deprecated on_demand 'ask' URL is run through the placeholder replacer (repl.ReplaceOrErr with error-on-failure) so environment variables like {$ASK_URL} can be substituted; per issue #5036 a silently-unresolved placeholder would surprise users, so failure is fatal. This error means the ask value contained a placeholder that could not be resolved (missing env var) — the empty string replacement was rejected.
Source
Thrown at modules/caddytls/tls.go:325
}
err = t.Automation.defaultInternalAutomationPolicy.Provision(t)
if err != nil {
return fmt.Errorf("provisioning default internal automation policy: %v", err)
}
break
}
for i, ap := range t.Automation.Policies {
err := ap.Provision(t)
if err != nil {
return fmt.Errorf("provisioning automation policy %d: %v", i, err)
}
}
// run replacer on ask URL (for environment variables) -- return errors to prevent surprises (#5036)
if t.Automation != nil && t.Automation.OnDemand != nil && t.Automation.OnDemand.Ask != "" {
t.Automation.OnDemand.Ask, err = repl.ReplaceOrErr(t.Automation.OnDemand.Ask, true, true)
if err != nil {
return fmt.Errorf("preparing 'ask' endpoint: %v", err)
}
perm := PermissionByHTTP{
Endpoint: t.Automation.OnDemand.Ask,
}
if err := perm.Provision(ctx); err != nil {
return fmt.Errorf("provisioning 'ask' module: %v", err)
}
t.Automation.OnDemand.permission = perm
}
// session ticket ephemeral keys (STEK) service and provider
if t.SessionTickets != nil {
err := t.SessionTickets.provision(ctx)
if err != nil {
return fmt.Errorf("provisioning session tickets configuration: %v", err)
}
}
View on GitHub (pinned to 50e54ee279)
Solutions
- Export the environment variable before starting Caddy (systemd Environment=, docker -e, .env source)
- Or replace the placeholder with a literal URL if the value is static
- Verify with 'caddy environ' or 'systemctl show caddy -p Environment' that the variable is present
Example fix
# before
"on_demand": {"ask": "{$ON_DEMAND_ASK}"} # env var unset -> error
# after
$ export ON_DEMAND_ASK=http://localhost:5555/check
$ caddy run --config Caddyfile Defensive patterns
Strategy: validation
Validate before calling
endpoint := os.Getenv("ON_DEMAND_ASK")
if endpoint == "" {
return fmt.Errorf("ON_DEMAND_ASK must be set; it is used in the config")
} Prevention
- Declare all env vars referenced by config in the service unit/container spec
- List required env vars in deployment docs and check them with a pre-start script
When it happens
Trigger: on_demand.ask = "{$ON_DEMAND_ASK}" but the ON_DEMAND_ASK environment variable is not set in Caddy's process environment; or a malformed placeholder syntax that the replacer treats as an error under ReplaceOrErr's strict mode.
Common situations: Deploying with systemd/container where the env var is defined in dev but absent in prod; renaming the variable; running under a service manager that strips environment.
Related errors
- on-demand TLS config conflict: both 'ask' endpoint and a 'pe
- loading on-demand TLS permission module: %v
- provisioning 'ask' module: %v
- replacing listen address: %v
- consolidating TLS connection policies for server %d: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/44979a42d53527f5.
Report an issue: GitHub.