caddyserver/caddy · error

reading config from file: %v

Error message

reading config from file: %v

What it means

os.ReadFile on the explicitly given --config file failed, wrapped as 'reading config from file'. The underlying error is almost always 'no such file or directory' or 'permission denied' for that exact path.

Source

Thrown at cmd/main.go:172

	if adapterName != "" && configFile == "" {
		return nil, "", "", fmt.Errorf("cannot adapt config without config file (use --config)")
	}

	// load initial config and adapter
	var config []byte
	var cfgAdapter caddyconfig.Adapter
	var err error
	if configFile != "" {
		if configFile == "-" {
			config, err = io.ReadAll(os.Stdin)
			if err != nil {
				return nil, "", "", fmt.Errorf("reading config from stdin: %v", err)
			}
			logger.Info("using config from stdin")
		} else {
			config, err = os.ReadFile(configFile)
			if err != nil {
				return nil, "", "", fmt.Errorf("reading config from file: %v", err)
			}
			logger.Info("using config from file", zap.String("file", configFile))
		}
	} else if adapterName == "" {
		// if the Caddyfile adapter is plugged in, we can try using an
		// adjacent Caddyfile by default
		cfgAdapter = caddyconfig.GetAdapter("caddyfile")
		if cfgAdapter != nil {
			config, err = os.ReadFile("Caddyfile")
			if errors.Is(err, fs.ErrNotExist) {
				// okay, no default Caddyfile; pretend like this never happened
				cfgAdapter = nil
			} else if err != nil {
				// default Caddyfile exists, but error reading it
				return nil, "", "", fmt.Errorf("reading default Caddyfile: %v", err)
			} else {
				// success reading default Caddyfile
				configFile = "Caddyfile"

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Verify the path: ls -l <config> from the same user and working directory
  2. Use an absolute path in --config, especially in service units
  3. Fix read permissions on the file (and execute permission on parent dirs)

Example fix

# before
ExecStart=/usr/bin/caddy run --config Caddyfile

# after
ExecStart=/usr/bin/caddy run --config /etc/caddy/Caddyfile
Defensive patterns

Strategy: validation

Validate before calling

# Resolve and stat the config before invoking caddy:
CONFIG=$(realpath "$CONFIG")
[ -r "$CONFIG" ] || { echo "cannot read $CONFIG" >&2; exit 1; }

Prevention

When it happens

Trigger: Typo'd or wrong-case path in --config; file exists but the running user lacks read permission; relative path interpreted against an unexpected working directory (systemd, cron).

Common situations: Service units with WorkingDirectory! set so a relative --config resolves wrong; permissions tightened on /etc/caddy; configs generated to a temp path that was cleaned up.

Related errors


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