{"record":{"id":"df91f71472bda573","repo":"grpc/grpc-go","slug":"cannot-have-exclude-and-a-wildcard","errorCode":null,"errorMessage":"cannot have exclude and a '*' wildcard","messagePattern":"cannot have exclude and a '\\*' wildcard","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gcp/observability/config.go","lineNumber":80,"sourceCode":"\t}\n\tserviceMethod := strings.Split(method, \"/\")\n\tif len(serviceMethod) != 2 {\n\t\treturn errors.New(\"/ must come in between service and method, only one /\")\n\t}\n\tif serviceMethod[1] == \"\" {\n\t\treturn errors.New(\"method name must be non empty\")\n\t}\n\tif serviceMethod[0] == \"*\" {\n\t\treturn errors.New(\"cannot have service wildcard * i.e. (*/m)\")\n\t}\n\treturn nil\n}\n\nfunc validateLogEventMethod(methods []string, exclude bool) error {\n\tfor _, method := range methods {\n\t\tif method == \"*\" {\n\t\t\tif exclude {\n\t\t\t\treturn errors.New(\"cannot have exclude and a '*' wildcard\")\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif err := validateMethodString(method); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid method string: %v, err: %v\", method, err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc validateLoggingEvents(config *config) error {\n\tif config.CloudLogging == nil {\n\t\treturn nil\n\t}\n\tfor _, clientRPCEvent := range config.CloudLogging.ClientRPCEvents {\n\t\tif err := validateLogEventMethod(clientRPCEvent.Methods, clientRPCEvent.Exclude); err != nil {\n\t\t\treturn fmt.Errorf(\"error in clientRPCEvent method: %v\", err)\n\t\t}","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/gcp/observability/config.go#L62-L98","documentation":"Returned by validateLogEventMethod (gcp/observability/config.go:80) when a methods entry equals exactly \"*\" AND the exclude flag on that RPC-events block is true. The \"*\" wildcard selects all methods; using it with exclude:true would mean 'exclude everything' which is nonsensical for logging, so the config rejects it. The check at line 78 short-circuits: a bare \"*\" is only valid when exclude is false.","triggerScenarios":"An observability config block like {\"methods\":[\"*\"],\"exclude\":true} in either client_rpc_events or server_rpc_events. Surfaces during unmarshalAndVerifyConfig while parsing GRPC_GCP_OBSERVABILITY_CONFIG(_FILE).","commonSituations":"Wanting 'log nothing except X' and incorrectly modeling it as exclude:true with a wildcard; copy-pasting an exclude block and adding a wildcard; misunderstanding that exclude works on the listed method set, not as a global toggle.","solutions":["Either set exclude:false with \"*\" (log everything), or keep exclude:true but list specific methods to exclude.","To express 'log everything except a few', use one inclusive block with \"*\" (exclude:false) and a separate mechanism, or list the methods you want with exclude semantics.","Re-read the config docs: '*' is not allowed when exclude is true."],"exampleFix":"// before\n{\"client_rpc_events\":[{\"methods\":[\"*\"],\"exclude\":true}]} // err\n\n// after (log everything)\n{\"client_rpc_events\":[{\"methods\":[\"*\"]}]}\n// or exclude specific methods:\n{\"client_rpc_events\":[{\"methods\":[\"foo.Bar/Noisy\"],\"exclude\":true}]}","handlingStrategy":"validation","validationCode":"for _, m := range methods {\n    if m == \"*\" && exclude {\n        return errors.New(\"'*' wildcard is not allowed when exclude is true\")\n    }\n}","typeGuard":null,"tryCatchPattern":"if _, err := unmarshalAndVerifyConfig(raw); err != nil { log.Fatalf(\"observability: %v\", err) }","preventionTips":["Document the exclude+wildcard rule next to your config template.","Prefer explicit method lists over broad wildcards with exclude."],"tags":["go","grpc","observability","config-validation","logging"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}