cilium/cilium · error
Invalid header action: %s
Error message
Invalid header action: %s
What it means
For HeaderMatches with an action (Mismatch field), Validate only accepts "", Log, Add, Delete, or Replace (the MismatchAction* constants). Any other string — e.g. a misspelled or wrongly-cased action — fails with this error naming the bad value.
Source
Thrown at pkg/policy/api/http.go:146
if h.Method != "" {
_, err := regexp.Compile(h.Method)
if err != nil {
return err
}
}
// Headers are not sanitized.
// But HeaderMatches are
for _, m := range h.HeaderMatches {
if m.Name == "" {
return fmt.Errorf("Header name missing")
}
if m.Mismatch != "" &&
m.Mismatch != MismatchActionLog && m.Mismatch != MismatchActionAdd &&
m.Mismatch != MismatchActionDelete && m.Mismatch != MismatchActionReplace {
return fmt.Errorf("Invalid header action: %s", m.Mismatch)
}
if m.Secret != nil && m.Secret.Name == "" {
return fmt.Errorf("Secret name missing")
}
}
return nil
}
View on GitHub (pinned to ac7b90affa)
Solutions
- Use exactly one of the supported actions: Log, Add, Delete, or Replace (match the constant casing) — or leave mismatch empty to only match without modifying.
- Check the Cilium version's MismatchAction constants in pkg/policy/api/http.go, as accepted values may differ across releases.
- Fix typos and casing; the error message echoes the offending string so compare it character-by-character.
- Pre-validate the action against a set before submitting the policy.
Example fix
// before (invalid) headerMatches: - name: "X-Trace" mismatch: set value: "abc" // after headerMatches: - name: "X-Trace" mismatch: replace value: "abc"
Defensive patterns
Strategy: validation
Validate before calling
var allowedActions = map[string]bool{"": true, "Log": true, "Add": true, "Delete": true, "Replace": true}
func validHeaderAction(m api.HeaderMatch) error {
if !allowedActions[m.Mismatch] {
return fmt.Errorf("action %q not in Log|Add|Delete|Replace", m.Mismatch)
}
return nil
} Type guard
func isKnownMismatchAction(a api.MismatchAction) bool {
switch a {
case "", api.MismatchActionLog, api.MismatchActionAdd, api.MismatchActionDelete, api.MismatchActionReplace:
return true
}
return false
} Try / catch
if err := httpRule.Validate(); err != nil {
if strings.Contains(err.Error(), "Invalid header action") {
return fmt.Errorf("unsupported action; use Log, Add, Delete or Replace: %w", err)
}
return err
} Prevention
- Use the api.MismatchAction* constants instead of raw strings
- Match exact casing — actions are compared with ==
- Check accepted values for your Cilium version before upgrading policies
- Add an enum-level schema constraint in your policy generation tooling
When it happens
Trigger: Setting headerMatches[].mismatch (action) to an unsupported value such as "set", "ADD", "Remove", or "append" in an HTTP L7 rule; Validate() is invoked during policy parsing.
Common situations: Copy-pasting actions from documentation of other proxies (e.g. Envoy's 'replace' vs Cilium's exact casing); typos like 'replce'; assuming case-insensitivity ('log' vs 'Log'); schema drift between Cilium versions.
Related errors
- Header name missing
- Secret name missing
- multiple L7 protocol rule types specified in single rule
- the ICMPs block may only be present without ToPorts. Define
- empty server name is not allowed
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/ebbb5e88b2c44f00.
Report an issue: GitHub.