{"record":{"id":"4f43409f0d6236e4","repo":"grpc/grpc-go","slug":"rbac-error-parsing-config-v-unknown-type-t","errorCode":null,"errorMessage":"rbac: error parsing config %v: unknown type %T","messagePattern":"rbac: error parsing config (.+?): unknown type %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/rbac/rbac.go","lineNumber":191,"sourceCode":"\tif name == \":scheme\" {\n\t\treturn fmt.Errorf(\"rbac: header matcher for %q is %q\", name, \":scheme\")\n\t}\n\tif strings.HasPrefix(name, \"grpc-\") {\n\t\treturn fmt.Errorf(\"rbac: header matcher for %q starts with %q\", name, \"grpc-\")\n\t}\n\tif name == \"host\" {\n\t\theader.Name = \":authority\"\n\t}\n\treturn 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}\n\treturn parseConfig(msg)\n}\n\nfunc (builder) ParseFilterConfigOverride(override proto.Message) (httpfilter.FilterConfig, error) {\n\tif override == nil {\n\t\treturn nil, fmt.Errorf(\"rbac: nil configuration message provided\")\n\t}\n\tm, ok := override.(*anypb.Any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"rbac: error parsing override config %v: unknown type %T\", override, override)\n\t}\n\tmsg := new(rpb.RBACPerRoute)\n\tif err := m.UnmarshalTo(msg); err != nil {","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/httpfilter/rbac/rbac.go#L173-L209","documentation":"ParseFilterConfig (rbac.go:190) requires cfg to be *anypb.Any. The type assertion fails for any other concrete proto.Message type (e.g., passing the *rpb.RBAC directly instead of wrapping it in an Any).","triggerScenarios":"ParseFilterConfig is called with a proto.Message that is not *anypb.Any — most commonly a *rpb.RBAC or a *v3rbacpb.RBAC passed directly, or a different filter's config.","commonSituations":"Programmatic test/registration passing the unwrapped proto; control-plane bug sending the raw proto; cross-wiring configs between filters.","solutions":["Wrap the rpb.RBAC proto in an anypb.Any via anypb.New before passing.","Verify the type URL matches one of the builder's TypeURLs() (RBAC or RBACPerRoute).","Use TypeURLs() as the canonical list of acceptable URLs."],"exampleFix":"// before\ncfg, err := rbacBuilder.ParseFilterConfig(&rpb.RBAC{Rules: ...})\n\n// after\nanyCfg, _ := anypb.New(&rpb.RBAC{Rules: ...})\ncfg, err := rbacBuilder.ParseFilterConfig(anyCfg)","handlingStrategy":"type-guard","validationCode":"if _, ok := cfg.(*anypb.Any); !ok {\n    return nil, fmt.Errorf(\"rbac: expected *anypb.Any, got %T\", cfg)\n}","typeGuard":"func isAnyPB(m proto.Message) bool { _, ok := m.(*anypb.Any); return ok }","tryCatchPattern":"if _, ok := cfg.(*anypb.Any); !ok {\n    anyCfg, err := anypb.New(cfg)\n    if err != nil { return err }\n    cfg = anyCfg\n}\nfc, err := rbacBuilder.ParseFilterConfig(cfg)","preventionTips":["Wrap rpb.RBAC in anypb.New before parsing.","Validate the config type at the control-plane."],"tags":["rbac","config","type","xds","grpc"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}