{"record":{"id":"6f67689f50896f17","repo":"grpc/grpc-go","slug":"rbac-error-constructing-matching-engine-v","errorCode":null,"errorMessage":"rbac: error constructing matching engine: %v","messagePattern":"rbac: error constructing matching engine: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/rbac/rbac.go","lineNumber":122,"sourceCode":"\n\t// Two cases where this HTTP Filter is a no op:\n\t// \"If absent, no enforcing RBAC policy will be applied\" - RBAC\n\t// Documentation for Rules field.\n\t// \"At this time, if the RBAC.action is Action.LOG then the policy will be\n\t// completely ignored, as if RBAC was not configured.\" - A41\n\tif rbacCfg.Rules == nil || rbacCfg.GetRules().GetAction() == v3rbacpb.RBAC_LOG {\n\t\treturn config{}, nil\n\t}\n\n\t// TODO(gregorycooke) - change the call chain to here so we have the filter\n\t// name to input here instead of an empty string. It will come from here:\n\t// https://github.com/grpc/grpc-go/blob/eff0942e95d93112921414aee758e619ec86f26f/xds/internal/xdsclient/xdsresource/unmarshal_lds.go#L199\n\tce, err := rbac.NewChainEngine([]*v3rbacpb.RBAC{rbacCfg.GetRules()}, \"\")\n\tif err != nil {\n\t\t// \"At this time, if the RBAC.action is Action.LOG then the policy will be\n\t\t// completely ignored, as if RBAC was not configured.\" - A41\n\t\tif rbacCfg.GetRules().GetAction() != v3rbacpb.RBAC_LOG {\n\t\t\treturn nil, fmt.Errorf(\"rbac: error constructing matching engine: %v\", err)\n\t\t}\n\t}\n\n\treturn config{chainEngine: ce}, nil\n}\n\nfunc (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {\n\tif cfg == nil {\n\t\treturn nil, fmt.Errorf(\"rbac: nil configuration message provided\")\n\t}\n\tm, ok := cfg.(*anypb.Any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"rbac: error parsing config %v: unknown type %T\", cfg, cfg)\n\t}\n\tmsg := new(rpb.RBAC)\n\tif err := m.UnmarshalTo(msg); err != nil {\n\t\treturn nil, fmt.Errorf(\"rbac: error parsing config %v: %v\", cfg, err)\n\t}","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/httpfilter/rbac/rbac.go#L104-L140","documentation":"The RBAC filter builds a matching chain engine from the rules via rbac.NewChainEngine. If construction fails (e.g. an unsupported matcher variant, malformed regex, malformed CIDR), the underlying error is wrapped and returned, but only when the action is not LOG (LOG-action policies are silently treated as no-op).","triggerScenarios":"A structurally-valid RBAC protobuf whose matchers are semantically invalid is delivered by the control plane: bad regex in a string matcher, malformed IP/CIDR range, or a matcher variant that grpc-go's ChainEngine does not implement.","commonSituations":"Control-plane/Envoy version newer than the grpc-go RBAC implementation emitting a matcher type grpc-go cannot compile; hand-authored policy with an invalid regex; partial proto from a buggy xDS server.","solutions":["Read the wrapped error (the %v) to find the specific matcher the ChainEngine rejected.","Fix the offending matcher (regex escaping, CIDR notation, supported matcher kind) in the control-plane policy.","If the matcher requires a newer Envoy feature, either downgrade the policy or upgrade grpc-go to a version that supports it."],"exampleFix":"// before: permission with a malformed regex\n//   - header:\n//       name: x-trace-id\n//       safe_regex_match: { regex: \"[a-z\" }   // unterminated\n//\n// after\n//   - header:\n//       name: x-trace-id\n//       safe_regex_match: { regex: \"[a-z]+\" }","handlingStrategy":"validation","validationCode":"// Pre-build the chain engine on the control plane (or in a test) to catch\n// matcher errors before serving the resource.\nfunc preflightChainEngine(rules *rbacpb.RBAC) error {\n\t_, err := rbacfilter.NewChainEngine([]*rbacpb.RBAC{rules}, \"\")\n\treturn err\n}","typeGuard":null,"tryCatchPattern":"// When consuming xDS updates, isolate RBAC parse failures so one bad\n// resource does not tear down the whole listener.\n//   fc, err := builder.ParseFilterConfig(anyCfg)\n//   if err != nil {\n//       log rbac failure, nack the resource, keep previous config\n//   }","preventionTips":["Unit-test each RBAC policy against rbac.NewChainEngine before deploying.","Keep grpc-go and the control plane on compatible Envoy API versions."],"tags":["rbac","xds","grpc","envoy","matcher-engine"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}