grpc/grpc-go · error
httpfilter: %v
Error message
httpfilter: %v
What it means
Raised by HeaderMutationRulesFromProto (extconfig.go:78) when the allow_expression regex in a HeaderMutationRules proto cannot be compiled. The library wraps the inner matcher.CompileSafeRegex error with the 'httpfilter:' prefix; an invalid regex means the rules cannot be enforced, so the filter config (ext_authz or ext_proc) is rejected.
Source
Thrown at internal/xds/httpfilter/extconfig.go:78
if err != nil {
return nil, err
}
matchers = append(matchers, sm)
}
return matchers, nil
}
// HeaderMutationRulesFromProto converts a protobuf HeaderMutationRules proto
// message to a HeaderMutationRules struct.
func HeaderMutationRulesFromProto(mr *v3mutationpb.HeaderMutationRules) (HeaderMutationRules, error) {
var rules HeaderMutationRules
if mr == nil {
return rules, nil
}
if allowExpr := mr.GetAllowExpression(); allowExpr != nil {
re, err := matcher.CompileSafeRegex(allowExpr.GetRegex())
if err != nil {
return rules, fmt.Errorf("httpfilter: %v", err)
}
rules.AllowExpr = re
}
if disallowExpr := mr.GetDisallowExpression(); disallowExpr != nil {
re, err := matcher.CompileSafeRegex(disallowExpr.GetRegex())
if err != nil {
return rules, fmt.Errorf("httpfilter: %v", err)
}
rules.DisallowExpr = re
}
rules.DisallowAll = mr.GetDisallowAll().GetValue()
rules.DisallowIsError = mr.GetDisallowIsError().GetValue()
return rules, nil
}
// ApplyAdditions takes a set of header mutations (for additions and
// modifications) received from an external server and applies them to the
// provided metadata, subject to the rules defined in hmr.View on GitHub (pinned to 03255a9237)
Solutions
- Read the inner %v — it is the exact RE2 syntax error with position.
- Replace the pattern with a valid RE2 regex (no backreferences, no lookahead); test it with `regexp.Compile` / `protoc` before publishing.
- Note CompileSafeRegex anchors the pattern as ^(?:PATTERN)$, so ensure your pattern is meant to match the whole header name.
Example fix
// before
// allow_expression: { regex: "x-[a-z" } // unclosed class -> error 366
//
// after
// allow_expression: { regex: "x-[a-z]+" } Defensive patterns
Strategy: validation
Validate before calling
// Pre-compile allow_expression the way the filter will (string_matcher.go:224-228,
// wrapped at extconfig.go:78).
func validateAllowRegex(re *envoy_type_matcher.RegexMatcher) error {
if re == nil {
return nil
}
if _, err := regexp.Compile(re.GetRegex()); err != nil {
return fmt.Errorf("httpfilter: %w", err)
}
// CompileSafeRegex also anchors as ^(?:...)$; verify that compiles too.
if _, err := regexp.Compile(fmt.Sprintf("^(?:%s)$", re.GetRegex())); err != nil {
return err
}
return nil
} Prevention
- Remember the filter matches the FULL header name (^...$); design patterns accordingly.
- Test every regex with Go's regexp.Compile (RE2) before publishing — no backreferences/lookahead.
- Add a CI lint that compiles all regex fields in xDS resources.
When it happens
Trigger: The decoder_header_mutation_rules / mutation_rules allow_expression.regex (RE2 syntax) is malformed, so regexp.Compile at string_matcher.go:225 fails and the error is propagated at extconfig.go:78.
Common situations: A regex with constructs RE2 rejects (e.g. backreferences '\1', unbalanced parentheses, invalid escape sequences); a typo like '[a-z' (unclosed class); copy-pasting a PCRE pattern into the xDS config.
Related errors
- missing server_listener_resource_name_template in the bootst
- OutlierDetectionLoadBalancingConfig.interval = %s; must be >
- OutlierDetectionLoadBalancingConfig.base_ejection_time = %s;
- OutlierDetectionLoadBalancingConfig.max_ejection_time = %s;
- OutlierDetectionLoadBalancingConfig.max_ejection_percent = %
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/3b73fb72b6de1871.
Report an issue: GitHub.