caddyserver/caddy · error

marshaling %T matcher: %v

Error message

marshaling %T matcher: %v

What it means

After a connection matcher is parsed from a Caddyfile, Caddy json.Marshal's it to store in the ModuleMap of the connection policy; if marshaling fails (unexported fields with no JSON tags, unsupported types like func or chan in the matcher struct), this error wraps the json error.

Source

Thrown at modules/caddytls/connpolicy.go:1125

		dd := caddyfile.NewDispenser(tokens)
		dd.Next() // consume wrapper name

		unm, err := caddyfile.UnmarshalModule(dd, "tls.handshake_match."+matcherName)
		if err != nil {
			return nil, err
		}
		cm, ok := unm.(ConnectionMatcher)
		if !ok {
			return nil, fmt.Errorf("matcher module '%s' is not a connection matcher", matcherName)
		}
		matcherMap[matcherName] = cm
	}

	matcherSet := make(caddy.ModuleMap)
	for name, matcher := range matcherMap {
		jsonBytes, err := json.Marshal(matcher)
		if err != nil {
			return nil, fmt.Errorf("marshaling %T matcher: %v", matcher, err)
		}
		matcherSet[name] = jsonBytes
	}

	return matcherSet, nil
}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. If this is your plugin, ensure all config fields are exported and JSON-marshalable; keep runtime-only state in separate unexported-but-ignored fields (add json:"-" where needed)
  2. Rebuild the plugin against the deployed Caddy version
  3. If stock Caddy hits this, report it — it indicates a regression in a built-in matcher
Defensive patterns

Strategy: validation

Validate before calling

// Plugin authors: unit-test that matcher config marshals cleanly
func TestMatcherMarshals(t *testing.T) {
	b, err := json.Marshal(&MyMatcher{ /* exported config fields */ })
	if err != nil {
		t.Fatalf("matcher not JSON-safe: %v", err)
	}
	t.Log(string(b))
}

Prevention

When it happens

Trigger: Almost exclusively with third-party matcher modules whose structs contain unmarshalable fields; stock matchers marshal fine.

Common situations: Custom handshake matcher plugins during development; Go json rejecting types such as sync.Mutex, channels, or unexported complex fields.

Related errors


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