caddyserver/caddy · warning

syntax error: unexpected token '%s', expecting '%s', at %s:%

Error message

syntax error: unexpected token '%s', expecting '%s', at %s:%d import chain: ['%s']

What it means

The current STEK in storage passed its NextRotation deadline, so the provider called rotateKeys to generate and persist new keys, and rotation failed. This happens on the background rotation timer, meaning existing keys keep working but no new resumption keys are issued until rotation succeeds.

Source

Thrown at caddyconfig/caddyfile/dispenser.go:423

	d.nesting = 0
}

// ArgErr returns an argument error, meaning that another
// argument was expected but not found. In other words,
// a line break or open curly brace was encountered instead of
// an argument.
func (d *Dispenser) ArgErr() error {
	if isOpenCurlyBrace(d.Token()) {
		return d.Err("unexpected token '{', expecting argument")
	}
	return d.Errf("wrong argument count or unexpected line ending after '%s'", d.Val())
}

// SyntaxErr creates a generic syntax error which explains what was
// found and what was expected.
func (d *Dispenser) SyntaxErr(expected string) error {
	msg := fmt.Sprintf("syntax error: unexpected token '%s', expecting '%s', at %s:%d import chain: ['%s']", d.Val(), expected, d.File(), d.Line(), strings.Join(d.Token().imports, "','"))
	return errors.New(msg)
}

// EOFErr returns an error indicating that the dispenser reached
// the end of the input when searching for the next token.
func (d *Dispenser) EOFErr() error {
	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...))
}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Read the wrapped error to distinguish generation vs 'storing STEK gob' storage failures.
  2. Free disk space / restore write access / refresh storage credentials on the node.
  3. In mixed-version clusters, upgrade all instances together so the persisted gob schema matches.
  4. Restart Caddy after fixing storage; the next rotation attempt will succeed and resume normal rotation scheduling.
Defensive patterns

Strategy: retry

Try / catch

Background rotation failure: existing keys remain valid, so log and alert rather than crash; rotation retries on subsequent ticks once storage recovers.

Prevention

When it happens

Trigger: Timer fires, getSTEK runs, time.Now().After(dstek.NextRotation) is true, and rotateKeys fails at either key generation or storage.Store of the new STEK gob.

Common situations: Storage became read-only or unreachable after initial provisioning; disk full on the data volume; storage credentials expired between rotations; a schema change in distributedSTEK gob encoding after a mixed-version cluster upgrade.

Understand the failure class

Related errors


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