{"record":{"id":"f9add31e63a98989","repo":"grpc/grpc-go","slug":"extauthz-error-parsing-config-v-unknown-type-t","errorCode":null,"errorMessage":"extauthz: error parsing config %v: unknown type %T, want *anypb.Any","messagePattern":"extauthz: error parsing config (.+?): unknown type %T, want \\*anypb\\.Any","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/ext_authz/ext_authz.go","lineNumber":95,"sourceCode":"\t}\n\n\t// If the numerator exceeds the denominator, cap the fractional value at 100%.\n\tnum := min(fracPercent.GetNumerator(), den)\n\treturn fraction{numerator: num, denominator: den}, nil\n}\n\n// grpcStatusCode converts an HTTP status code to a gRPC status code.\nfunc grpcStatusCode(httpStatus int32) codes.Code {\n\tif code, ok := transport.HTTPStatusConvTab[int(httpStatus)]; ok {\n\t\treturn code\n\t}\n\treturn codes.Unknown\n}\n\nfunc (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) {\n\tm, ok := cfg.(*anypb.Any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"extauthz: error parsing config %v: unknown type %T, want *anypb.Any\", cfg, cfg)\n\t}\n\tmsg := new(v3extauthzpb.ExtAuthz)\n\tif err := m.UnmarshalTo(msg); err != nil {\n\t\treturn nil, fmt.Errorf(\"extauthz: failed to unmarshal config: %v\", err)\n\t}\n\n\tif msg.GetGrpcService() == nil {\n\t\treturn nil, fmt.Errorf(\"extauthz: empty grpc_service provided in config %v\", cfg)\n\t}\n\tserver, err := parseGRPCServiceConfig(msg.GetGrpcService())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"extauthz: failed to parse grpc_service: %v\", err)\n\t}\n\n\tfilterEnabled, err := parseFilterEnabled(msg.GetFilterEnabled())\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/httpfilter/ext_authz/ext_authz.go#L77-L113","documentation":"ParseFilterConfig expected the configuration wrapped as *anypb.Any but received a different concrete proto type (ext_authz.go:93-95). xDS HTTP filter configs are always transported as Any-wrapped messages, so receiving a bare proto indicates an integration-layer error.","triggerScenarios":"The httpfilter framework calls ParseFilterConfig with a proto.Message whose concrete type is not *anypb.Any (e.g. an already-unwrapped ExtAuthz proto passed by custom integration or test code).","commonSituations":"Custom httpfilter integration that unwraps Any before dispatching to the filter parser; incorrect framework wiring; test code passing a bare ExtAuthz proto instead of wrapping it in anypb.New().","solutions":["Ensure the httpfilter framework passes *anypb.Any to ParseFilterConfig","Wrap the config proto with anypb.New() before calling the parser in test code","Do not manually unwrap Any before dispatching to filter parsers"],"exampleFix":"// before — bare proto passed\ncfg := &v3extauthzpb.ExtAuthz{GrpcService: gs}\nfc, err := builder{}.ParseFilterConfig(cfg)\n\n// after — wrap in Any first\nanyCfg, _ := anypb.New(cfg)\nfc, err := builder{}.ParseFilterConfig(anyCfg)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Ensure the config is *anypb.Any before passing to the parser.\nfunc isAnyProto(msg proto.Message) bool {\n    _, ok := msg.(*anypb.Any)\n    return ok\n}","tryCatchPattern":null,"preventionTips":["Always pass *anypb.Any to httpfilter parsers — the framework handles unwrapping","Use anypb.New() to wrap protos in test code before calling parser methods","Do not manually unwrap Any messages before dispatching to filter parsers"],"tags":["ext-authz","xds","http-filter","type-assertion"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}