caddyserver/caddy · error
%s is %w
Error message
%s is %w
What it means
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.
Source
Thrown at modules/caddyhttp/proxyprotocol/policy.go:79
return []byte(policyMap[x]), nil
}
// UnmarshalText implements the text unmarshaller method.
func (x *Policy) UnmarshalText(text []byte) error {
name := string(text)
tmp, err := parsePolicy(name)
if err != nil {
return err
}
*x = tmp
return nil
}
func parsePolicy(name string) (Policy, error) {
if x, ok := policyMapRev[strings.ToUpper(name)]; ok {
return x, nil
}
return Policy(0), fmt.Errorf("%s is %w", name, errInvalidPolicy)
}
var errInvalidPolicy = errors.New("invalid policy")
View on GitHub (pinned to 50e54ee279)
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.
Example fix
# before (Caddyfile)
{
servers {
listener_wrappers {
proxy_protocol allow
}
}
}
# after
{
servers {
listener_wrappers {
proxy_protocol USE
}
}
} Defensive patterns
Strategy: validation
Validate before calling
// before unmarshalling config text
var validPolicies = map[string]bool{"USE": true, "IGNORE": true, "REJECT": true, "REQUIRE": true, "SKIP": true}
func validPolicy(s string) bool { return validPolicies[strings.ToUpper(strings.TrimSpace(s))] }
if !validPolicy(cfg.Policy) {
return fmt.Errorf("policy must be one of USE, IGNORE, REJECT, REQUIRE, SKIP; got %q", cfg.Policy)
} Type guard
func isValidPolicy(name string) bool {
_, ok := map[string]struct{}{"USE": {}, "IGNORE": {}, "REJECT": {}, "REQUIRE": {}, "SKIP": {}}[strings.ToUpper(strings.TrimSpace(name))]
return ok
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- invalid action type
- no identifiers configured
- adapting config using %s: %v
- include and exclude must not intersect, but found %s in both
- unrecognized log level: %s
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/e4e529c74881a6b6.
Report an issue: GitHub.