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

  1. Fix the FIRST error — it names the app whose Start() failed; the 'additionally' clause is cleanup fallout.
  2. Address the second error only if it persists after the first is fixed (usually a plugin Stop() bug).
  3. Free conflicting ports/sockets, then retry; if shutdown left resources held, restart the process.
  4. 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

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


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/b810ed938aeb0f95. Report an issue: GitHub.