{"record":{"id":"e4e529c74881a6b6","repo":"caddyserver/caddy","slug":"s-is-w","errorCode":null,"errorMessage":"%s is %w","messagePattern":"%s is %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/proxyprotocol/policy.go","lineNumber":79,"sourceCode":"\treturn []byte(policyMap[x]), nil\n}\n\n// UnmarshalText implements the text unmarshaller method.\nfunc (x *Policy) UnmarshalText(text []byte) error {\n\tname := string(text)\n\ttmp, err := parsePolicy(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*x = tmp\n\treturn nil\n}\n\nfunc parsePolicy(name string) (Policy, error) {\n\tif x, ok := policyMapRev[strings.ToUpper(name)]; ok {\n\t\treturn x, nil\n\t}\n\treturn Policy(0), fmt.Errorf(\"%s is %w\", name, errInvalidPolicy)\n}\n\nvar errInvalidPolicy = errors.New(\"invalid policy\")\n","sourceCodeStart":61,"sourceCodeEnd":83,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/proxyprotocol/policy.go#L61-L83","documentation":"The PROXY protocol module's Policy type fails to parse the configured policy name. parsePolicy uppercases the input and looks it up in policyMapRev, which only knows USE, IGNORE, REJECT, REQUIRE, and SKIP. Any other string is wrapped with errInvalidPolicy via '%s is %w'. The lookup is case-insensitive, so 'use' works but 'enable' does not.","triggerScenarios":"Setting the 'policy' subdirective of the 'proxy_protocol' global option (Caddyfile) or the corresponding JSON field to a string outside {USE, IGNORE, REJECT, REQUIRE, SKIP} (case-insensitive). Also calling Policy.UnmarshalText directly (e.g. json.Unmarshal into a proxyprotocol.Policy) with an unrecognized value.","commonSituations":"Typos like 'reject ' with trailing whitespace (the value is not trimmed), 'ALLOW' or 'DENY' carried over from other PROXY-protocol implementations (HAProxy uses ACCEPT/IGNORE/REQUIRE), or a bare number where a name is expected.","solutions":["Set the policy to one of the five valid names: USE, IGNORE, REJECT, REQUIRE, or SKIP (any letter case).","Remove surrounding quotes/whitespace and re-run 'caddy validate --config <file>' to confirm the value parses.","If migrating from HAProxy-style configs, map ACCEPT->USE, IGNORE->IGNORE, REQUIRE->REJECT/REQUIRE depending on intent."],"exampleFix":"# before (Caddyfile)\n{\n  servers {\n    listener_wrappers {\n      proxy_protocol allow\n    }\n  }\n}\n\n# after\n{\n  servers {\n    listener_wrappers {\n      proxy_protocol USE\n    }\n  }\n}","handlingStrategy":"validation","validationCode":"// before unmarshalling config text\nvar validPolicies = map[string]bool{\"USE\": true, \"IGNORE\": true, \"REJECT\": true, \"REQUIRE\": true, \"SKIP\": true}\n\nfunc validPolicy(s string) bool { return validPolicies[strings.ToUpper(strings.TrimSpace(s))] }\n\nif !validPolicy(cfg.Policy) {\n    return fmt.Errorf(\"policy must be one of USE, IGNORE, REJECT, REQUIRE, SKIP; got %q\", cfg.Policy)\n}","typeGuard":"func isValidPolicy(name string) bool {\n\t_, ok := map[string]struct{}{\"USE\": {}, \"IGNORE\": {}, \"REJECT\": {}, \"REQUIRE\": {}, \"SKIP\": {}}[strings.ToUpper(strings.TrimSpace(name))]\n\treturn ok\n}","tryCatchPattern":null,"preventionTips":["Keep the five valid policy names in a shared constant list and lint configs against it.","Run 'caddy validate --config' in CI so policy typos fail before deploy.","Remember values are uppercased but not trimmed — never add surrounding whitespace."],"tags":["proxy-protocol","configuration","caddyfile","validation"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}