{"record":{"id":"3b73fb72b6de1871","repo":"grpc/grpc-go","slug":"httpfilter-v","errorCode":null,"errorMessage":"httpfilter: %v","messagePattern":"httpfilter: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/extconfig.go","lineNumber":78,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmatchers = append(matchers, sm)\n\t}\n\treturn matchers, nil\n}\n\n// HeaderMutationRulesFromProto converts a protobuf HeaderMutationRules proto\n// message to a HeaderMutationRules struct.\nfunc HeaderMutationRulesFromProto(mr *v3mutationpb.HeaderMutationRules) (HeaderMutationRules, error) {\n\tvar rules HeaderMutationRules\n\tif mr == nil {\n\t\treturn rules, nil\n\t}\n\tif allowExpr := mr.GetAllowExpression(); allowExpr != nil {\n\t\tre, err := matcher.CompileSafeRegex(allowExpr.GetRegex())\n\t\tif err != nil {\n\t\t\treturn rules, fmt.Errorf(\"httpfilter: %v\", err)\n\t\t}\n\t\trules.AllowExpr = re\n\t}\n\tif disallowExpr := mr.GetDisallowExpression(); disallowExpr != nil {\n\t\tre, err := matcher.CompileSafeRegex(disallowExpr.GetRegex())\n\t\tif err != nil {\n\t\t\treturn rules, fmt.Errorf(\"httpfilter: %v\", err)\n\t\t}\n\t\trules.DisallowExpr = re\n\t}\n\trules.DisallowAll = mr.GetDisallowAll().GetValue()\n\trules.DisallowIsError = mr.GetDisallowIsError().GetValue()\n\treturn rules, nil\n}\n\n// ApplyAdditions takes a set of header mutations (for additions and\n// modifications) received from an external server and applies them to the\n// provided metadata, subject to the rules defined in hmr.","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/httpfilter/extconfig.go#L60-L96","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n//   allow_expression: { regex: \"x-[a-z\" }   // unclosed class -> error 366\n//\n// after\n//   allow_expression: { regex: \"x-[a-z]+\" }","handlingStrategy":"validation","validationCode":"// Pre-compile allow_expression the way the filter will (string_matcher.go:224-228,\n// wrapped at extconfig.go:78).\nfunc validateAllowRegex(re *envoy_type_matcher.RegexMatcher) error {\n    if re == nil {\n        return nil\n    }\n    if _, err := regexp.Compile(re.GetRegex()); err != nil {\n        return fmt.Errorf(\"httpfilter: %w\", err)\n    }\n    // CompileSafeRegex also anchors as ^(?:...)$; verify that compiles too.\n    if _, err := regexp.Compile(fmt.Sprintf(\"^(?:%s)$\", re.GetRegex())); err != nil {\n        return err\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["grpc","xds","config","regex","header-mutation"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}