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
- Read the wrapped error to distinguish generation vs 'storing STEK gob' storage failures.
- Free disk space / restore write access / refresh storage credentials on the node.
- In mixed-version clusters, upgrade all instances together so the persisted gob schema matches.
- 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
- Monitor disk space and storage write health on nodes using distributed STEKs.
- Alert on repeated rotation failures so resumption-key rotation does not silently stall.
- Keep storage credentials valid across long uptimes (rotation errors can appear 7+ days after a credential lapse).
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- WebSocket connections aren't allowed.
- Disabling same-origin restrictions is not allowed.
- Buggy browser is sending null Origin header.
- --output is required
- cannot reuse socket %v: unix socket is already in use by ano
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/1640d311187c05d9.
Report an issue: GitHub.