caddyserver/caddy · error
%v; additionally, aborting app %s: %v
Error message
%v; additionally, aborting app %s: %v
What it means
During run(), if an app's Start() fails, Caddy stops every app that had already started to unwind cleanly. If stopping one of those already-started apps also fails, the stop error is chained onto the start error as '%v; additionally, aborting app %s: %v'. The primary error remains the app start failure; the secondary error only reports degraded shutdown, not the root cause.
Source
Thrown at caddy.go:454
if currentCtx.cfg != nil {
certmagic.Default.Storage = currentCtx.cfg.storage
}
}
}()
// Start
err = func() error {
started := make([]string, 0, len(ctx.cfg.apps))
for name, a := range ctx.cfg.apps {
err := a.Start()
if err != nil {
// an app failed to start, so we need to stop
// all other apps that were already started
for _, otherAppName := range started {
err2 := ctx.cfg.apps[otherAppName].Stop()
if err2 != nil {
err = fmt.Errorf("%v; additionally, aborting app %s: %v",
err, otherAppName, err2)
}
}
return fmt.Errorf("%s app module: start: %v", name, err)
}
started = append(started, name)
}
return nil
}()
if err != nil {
return ctx, err
}
globalMetrics.configSuccess.Set(1)
globalMetrics.configSuccessTime.SetToCurrentTime()
// TODO: This event is experimental and subject to change.
ctx.emitEvent("started", nil)
View on GitHub (pinned to 50e54ee279)
Solutions
- Fix the FIRST error — it names the app whose Start() failed; the 'additionally' clause is cleanup fallout.
- Address the second error only if it persists after the first is fixed (usually a plugin Stop() bug).
- Free conflicting ports/sockets, then retry; if shutdown left resources held, restart the process.
- For plugin authors: make Stop() idempotent and non-blocking on cancelled contexts.
Defensive patterns
Strategy: try-catch
Try / catch
ctx, err := caddy.Run(cfg)
if err != nil && strings.Contains(err.Error(), "additionally, aborting app") {
// start failure + dirty unwind: restart process for clean state
log.Fatalf("app start failed and unwind errored: %v", err)
} Prevention
- Fix primary Start() errors first; the 'additionally' clause is fallout.
- Plugin authors: implement Stop() idempotently and tolerate cancelled contexts.
- Ensure app resource conflicts (ports, sockets) are resolved before start.
When it happens
Trigger: A multi-app config (e.g. http + tls + pk + custom apps) where a later app fails Start() and an earlier app's Stop() then errors — e.g. an http app that cannot release listeners, or a plugin whose Stop has bugs. Map iteration order makes 'later' nondeterministic across apps.
Common situations: One app failing to bind its resources (port in use, bad socket) while another app's shutdown path is broken (plugin bug, context already cancelled); custom plugins with poorly implemented Stop(); rarely, TLS storage lock contention during unwind.
Related errors
- %s app module: start: %v
- server graceful shutdown %ds timeout
- method not allowed
- %v; additionally, cleanup: %v
- provision %s: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/b810ed938aeb0f95.
Report an issue: GitHub.