{"record":{"id":"74a6232a04ec806b","repo":"caddyserver/caddy","slug":"the-forwarded-option-is-no-longer-supported-use","errorCode":null,"errorMessage":"the 'forwarded' option is no longer supported; use the 'client_ip' matcher instead","messagePattern":"the 'forwarded' option is no longer supported; use the 'client_ip' matcher instead","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/ip_matchers.go","lineNumber":121,"sourceCode":"\t\t// name of the macro, this is the function name that users see when writing expressions.\n\t\t\"remote_ip\",\n\t\t// name of the function that the macro will be rewritten to call.\n\t\t\"remote_ip_match_request_list\",\n\t\t// internal data type of the MatchPath value.\n\t\t[]*cel.Type{cel.ListType(cel.StringType)},\n\t\t// function to convert a constant list of strings to a MatchPath instance.\n\t\tfunc(data ref.Val) (RequestMatcherWithError, error) {\n\t\t\trefStringList := stringSliceType\n\t\t\tstrList, err := data.ConvertToNative(refStringList)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tm := MatchRemoteIP{}\n\n\t\t\tfor _, input := range strList.([]string) {\n\t\t\t\tif input == \"forwarded\" {\n\t\t\t\t\treturn nil, errors.New(\"the 'forwarded' option is no longer supported; use the 'client_ip' matcher instead\")\n\t\t\t\t}\n\t\t\t\tm.Ranges = append(m.Ranges, input)\n\t\t\t}\n\n\t\t\terr = m.Provision(ctx)\n\t\t\treturn m, err\n\t\t},\n\t)\n}\n\n// Provision parses m's IP ranges, either from IP or CIDR expressions.\nfunc (m *MatchRemoteIP) Provision(ctx caddy.Context) error {\n\tm.logger = ctx.Logger()\n\tcidrs, zones, err := provisionCidrsZonesFromRanges(m.Ranges)\n\tif err != nil {\n\t\treturn err\n\t}\n\tm.cidrs = cidrs","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/ip_matchers.go#L103-L139","documentation":"Before publishing ECH configs, Caddy serializes the config list to its binary DNS wire format via echCfgList.MarshalBinary (the crypto/tls EncryptedClientHelloConfigList encoding). Marshal failed, meaning one of the in-memory ECH configs is malformed for wire encoding (bad config bytes, unsupported version, or an empty list edge case).","triggerScenarios":"tls.EncryptedClientHelloConfigList built from stored configs fails MarshalBinary: a config.bin entry loaded from storage is truncated/corrupt in a way that survived the load cleanup path, or a version/length field is inconsistent.","commonSituations":"Storage corruption of config.bin; a Caddy upgrade changing the expected binary layout while old configs remain in storage; hand-edited storage.","solutions":["Unwrap and inspect the MarshalBinary error for the offending config (often indicates a specific record length/version problem).","Stop Caddy and reset the ech/configs storage folder so fresh, well-formed configs are generated, then let publication repopulate DNS records.","After Caddy version upgrades with ECH enabled, expect rotation to replace old configs; if marshal fails immediately post-upgrade, reset state.","Verify no external tooling writes into Caddy's storage."],"exampleFix":"# before: publication fails on corrupt stored config\n# after: regenerate ECH state\nsystemctl stop caddy && rm -rf /var/lib/caddy/ech/configs && systemctl start caddy","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"On marshal failure of the config list, fall back to resetting ECH state: stop Caddy, back up and remove ech/configs, restart — fresh configs marshal cleanly and republish to DNS.","preventionTips":["Reset stored ECH state when upgrading across versions that change the binary config format.","Use atomic-write storage to prevent truncated config.bin.","Validate configs after restore: a successful start plus one publication cycle confirms wire-format health."],"tags":["caddy","caddytls","ech","dns","serialization"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}