caddyserver/caddy · critical
loading initial config: %v
Error message
loading initial config: %v
What it means
Returned by `caddy run` when the initial caddy.Load(config, true) fails during startup. Before returning, the buffered early logs are flushed to the default logger so the actual provisioning/validation failure is visible. This is the top-level 'your config could not start' error; the root cause is in the flushed log lines immediately above it.
Source
Thrown at cmd/commandfuncs.go:286
// If we have a source config file (we're running via 'caddy run --config ...'),
// record it so SIGUSR1 can reload from the same file. Also provide a callback
// that knows how to load/adapt that source when requested by the main process.
if configFile != "" {
caddy.SetLastConfig(configFile, adapterUsed, func(file, adapter string) error {
cfg, _, _, err := LoadConfig(file, adapter)
if err != nil {
return err
}
return caddy.Load(cfg, true)
})
}
// run the initial config
err = caddy.Load(config, true)
if err != nil {
logBuffer.FlushTo(defaultLogger)
return caddy.ExitCodeFailedStartup, fmt.Errorf("loading initial config: %v", err)
}
// release the reference to the config so it can be GC'd
config = nil //nolint:ineffassign,wastedassign
// at this stage the config will have replaced the
// default logger to the configured one, so we can
// log normally, now that the config is running.
// also clear our ref to the buffer so it can get GC'd
logger = caddy.Log()
defaultLogger = nil //nolint:ineffassign,wastedassign
logBuffer = nil //nolint:wastedassign,ineffassign
logger.Info("serving initial configuration")
// if we are to report to another process the successful start
// of the server, do so now by echoing back contents of stdin
if pingbackFlag != "" {
confirmationBytes, err := io.ReadAll(os.Stdin)
if err != nil {View on GitHub (pinned to 50e54ee279)
Solutions
- Read the log lines flushed just before this error — they contain the module-level cause
- Run caddy validate --config <file> --adapter <name> for a precise diagnostic
- If a module is unknown, rebuild with xcaddy --with <module> or use the full distribution
- Free conflicting ports or change listen addresses
Example fix
# before $ caddy run --config Caddyfile # Error: loading initial config: loading config: ... unknown module # after $ xcaddy build --with github.com/caddy-dns/cloudflare $ caddy run --config Caddyfile
Defensive patterns
Strategy: validation
Validate before calling
// validate the exact config before `caddy run`
if out, err := exec.Command("caddy", "validate", "--config", cfgPath, "--adapter", adapter).CombinedOutput(); err != nil {
return fmt.Errorf("refusing to run invalid config: %s", out)
} Try / catch
// in systemd unit: ExecStart=/usr/bin/caddy run --config /etc/caddy/Caddyfile // failures land in journalctl; alert on unit enter-failed state
Prevention
- Gate every deploy on caddy validate in CI
- After upgrades, re-validate: module IDs and schema can change between versions
- Watch the flushed early logs above the error — they name the failing module
When it happens
Trigger: Invalid JSON or Caddyfile syntax; unknown module IDs (plugin not compiled in); module Provision/Validate failures (bad listener addresses, invalid TLS automation, malformed matchers); port conflicts surface here too when servers bind.
Common situations: First run of a hand-edited config; upgrading Caddy major versions where config schema changed; custom builds missing standard modules; config referencing environment placeholders that resolved to empty values.
Related errors
- caddy process exited with error: %v
- parsing listener address: %v
- must be exactly one listener address; cannot listen on: %s
- indexing config: %v
- %s: %s field must be a string or number
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/dd463c97723ecd95.
Report an issue: GitHub.