caddyserver/caddy · error
cannot define both 'exclude' and 'include' lists at the same
Error message
cannot define both 'exclude' and 'include' lists at the same time
What it means
`copy_response_headers` accepts either an `include` or an `exclude` list of header names, but not both — they are mutually exclusive semantics (copy only these vs copy all but these). Validate() rejects the config at load time when both are non-empty.
Source
Thrown at modules/caddyhttp/reverseproxy/copyresponse.go:115
Exclude []string `json:"exclude,omitempty"`
includeMap map[string]struct{}
excludeMap map[string]struct{}
ctx caddy.Context
}
// CaddyModule returns the Caddy module information.
func (CopyResponseHeadersHandler) CaddyModule() caddy.ModuleInfo {
return caddy.ModuleInfo{
ID: "http.handlers.copy_response_headers",
New: func() caddy.Module { return new(CopyResponseHeadersHandler) },
}
}
// Validate ensures the h's configuration is valid.
func (h *CopyResponseHeadersHandler) Validate() error {
if len(h.Exclude) > 0 && len(h.Include) > 0 {
return fmt.Errorf("cannot define both 'exclude' and 'include' lists at the same time")
}
return nil
}
// Provision ensures that h is set up properly before use.
func (h *CopyResponseHeadersHandler) Provision(ctx caddy.Context) error {
h.ctx = ctx
// Optimize the include list by converting it to a map
if len(h.Include) > 0 {
h.includeMap = map[string]struct{}{}
}
for _, field := range h.Include {
h.includeMap[http.CanonicalHeaderKey(field)] = struct{}{}
}
// Optimize the exclude list by converting it to a mapView on GitHub (pinned to 50e54ee279)
Solutions
- Keep exactly one of include or exclude and delete the other
- If you need 'all except a few', use exclude only and remove the include list
- If you need 'only these', use include only
Example fix
# before
handle_response {
copy_response_headers {
include Content-Type
exclude Set-Cookie
}
}
# after
handle_response {
copy_response_headers {
include Content-Type
}
} Defensive patterns
Strategy: validation
Validate before calling
if len(include) > 0 && len(exclude) > 0 {
return fmt.Errorf("pick one: include (%d) or exclude (%d)", len(include), len(exclude))
} Prevention
- Treat include/exclude as mutually exclusive at the schema level in config templates
- When adding one, grep the config block for the other and delete it
When it happens
Trigger: Supplying both `include` and `exclude` subdirectives to copy_response_headers in the same handle_response block, or in JSON both the Include and Exclude arrays.
Common situations: Iteratively building config: a developer adds include, then later adds exclude to trim one more header instead of editing the include list, ending with both present.
Related errors
- cannot use 'copy_response' outside of reverse_proxy's handle
- cannot use 'copy_response_headers' outside of reverse_proxy'
- invalid action type
- %s is %w
- parsing upstream '%s': %w
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/e97336d8b243dd29.
Report an issue: GitHub.