caddyserver/caddy · warning

missing 'req' argument

Error message

missing 'req' argument

What it means

While rotating an ECH key, Caddy marks the old config's metadata as Replaced and json.Marshal of that metadata (echConfigMeta, which includes publication history maps with time.Time values) failed. Marshal failures here are practically impossible with well-formed structs — this indicates memory corruption or an unsupported dynamic value, and mainly serves as a defensive error path.

Source

Thrown at modules/caddyhttp/celmatcher.go:481

}

// CELMatcherDecorator matches a call overload generated by a CEL macro
// that takes a single argument, and optimizes the implementation to precompile
// the matcher and return a function that references the precompiled and
// provisioned matcher.
func CELMatcherDecorator(funcName string, fac any) interpreter.InterpretableDecorator {
	return func(i interpreter.Interpretable) (interpreter.Interpretable, error) {
		call, ok := i.(interpreter.InterpretableCall)
		if !ok {
			return i, nil
		}
		if call.OverloadID() != funcName {
			return i, nil
		}
		callArgs := call.Args()
		reqAttr, ok := callArgs[0].(interpreter.InterpretableAttribute)
		if !ok {
			return nil, errors.New("missing 'req' argument")
		}
		nsAttr, ok := reqAttr.Attr().(interpreter.NamespacedAttribute)
		if !ok {
			return nil, errors.New("missing 'req' argument")
		}
		varNames := nsAttr.CandidateVariableNames()
		if len(varNames) != 1 || len(varNames) == 1 && varNames[0] != CELRequestVarName {
			return nil, errors.New("missing 'req' argument")
		}
		matcherData, ok := callArgs[1].(interpreter.InterpretableConst)
		if !ok {
			// If the matcher arguments are not constant, then this means
			// they contain a Caddy placeholder reference and the evaluation
			// and matcher provisioning should be handled at dynamically.
			return i, nil
		}

		if factory, ok := fac.(CELMatcherWithErrorFactory); ok {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Treat as a bug: collect the wrapped error and report it upstream with the Caddy version.
  2. Restart the instance; rotation will re-attempt and re-derive metadata.
  3. If persistent, reset the ech/configs storage folder to regenerate clean metadata.
Defensive patterns

Strategy: try-catch

Try / catch

if err := rotateECHKeys(...); err != nil { if strings.Contains(err.Error(), "marshaling updated ECH config metadata") { /* defensive path: log details, restart to rebuild state */ } }

Prevention

When it happens

Trigger: json.Marshal(ech.configs[publicName][i].meta) returns an error, e.g. an unmarshalable type injected into the meta struct, or a NaN/unsupported value in publication history timestamps.

Common situations: Almost never seen in practice; would surface only from a bug in Caddy or a plugin writing invalid values into echConfigMeta. If seen, suspect a corrupted build or memory issue.

Related errors


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