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

  1. Read the log lines flushed just before this error — they contain the module-level cause
  2. Run caddy validate --config <file> --adapter <name> for a precise diagnostic
  3. If a module is unknown, rebuild with xcaddy --with <module> or use the full distribution
  4. 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

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


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