caddyserver/caddy · error

%w, at %s:%d

Error message

%w, at %s:%d

What it means

The plain variant of Dispenser.WrapErr: decorates a Caddyfile error with the current token's file and line when the token did NOT come from an import. This is the standard 'parse error at Caddyfile:N' formatter used by all directive parsing.

Source

Thrown at caddyconfig/caddyfile/dispenser.go:447

	return d.Errf("unexpected EOF")
}

// Err generates a custom parse-time error with a message of msg.
func (d *Dispenser) Err(msg string) error {
	return d.WrapErr(errors.New(msg))
}

// Errf is like Err, but for formatted error messages
func (d *Dispenser) Errf(format string, args ...any) error {
	return d.WrapErr(fmt.Errorf(format, args...))
}

// WrapErr takes an existing error and adds the Caddyfile file and line number.
func (d *Dispenser) WrapErr(err error) error {
	if len(d.Token().imports) > 0 {
		return fmt.Errorf("%w, at %s:%d import chain ['%s']", err, d.File(), d.Line(), strings.Join(d.Token().imports, "','"))
	}
	return fmt.Errorf("%w, at %s:%d", err, d.File(), d.Line())
}

// Delete deletes the current token and returns the updated slice
// of tokens. The cursor is not advanced to the next token.
// Because deletion modifies the underlying slice, this method
// should only be called if you have access to the original slice
// of tokens and/or are using the slice of tokens outside this
// Dispenser instance. If you do not re-assign the slice with the
// return value of this method, inconsistencies in the token
// array will become apparent (or worse, hide from you like they
// did me for 3 and a half freaking hours late one night).
func (d *Dispenser) Delete() []Token {
	if d.cursor >= 0 && d.cursor <= len(d.tokens)-1 {
		d.tokens = append(d.tokens[:d.cursor], d.tokens[d.cursor+1:]...)
		d.cursor--
	}
	return d.tokens
}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Go to Caddyfile at the reported line and fix the directive described in the error text
  2. Check the directive's docs for required arguments and subdirectives
  3. Run `caddy adapt --config Caddyfile` to reproduce quickly without starting the server
  4. If the syntax looks right, confirm your Caddy version supports the directive

Example fix

# before
respond "hi" "extra-arg"
# after
respond "hi"
Defensive patterns

Strategy: try-catch

Try / catch

if err := caddyfileUnmarshal(d); err != nil {
    // WrapErr already embeds file:line; return it unchanged up the stack
    return fmt.Errorf("caddyfile parse failed: %w", err)
}

Prevention

When it happens

Trigger: Any d.Err/d.Errf/d.WrapErr call on a token parsed directly from the top-level Caddyfile (empty imports list): unknown subdirective, wrong argument count, invalid value, etc.

Common situations: Typos in directives, missing required arguments, or Caddyfile syntax valid in an older Caddy version but no longer accepted. The reported line points at the offending token.

Related errors


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