{"record":{"id":"3ef380a2a739e9d4","repo":"grpc/grpc-go","slug":"conflicting-global-rules-found","errorCode":null,"errorMessage":"conflicting global rules found","messagePattern":"conflicting global rules found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/binarylog/binarylog.go","lineNumber":115,"sourceCode":"type logger struct {\n\tconfig LoggerConfig\n}\n\n// NewLoggerFromConfig builds a logger with the given LoggerConfig.\nfunc NewLoggerFromConfig(config LoggerConfig) Logger {\n\treturn &logger{config: config}\n}\n\n// newEmptyLogger creates an empty logger. The map fields need to be filled in\n// using the set* functions.\nfunc newEmptyLogger() *logger {\n\treturn &logger{}\n}\n\n// Set method logger for \"*\".\nfunc (l *logger) setDefaultMethodLogger(ml *MethodLoggerConfig) error {\n\tif l.config.All != nil {\n\t\treturn fmt.Errorf(\"conflicting global rules found\")\n\t}\n\tl.config.All = ml\n\treturn nil\n}\n\n// Set method logger for \"service/*\".\n//\n// New MethodLogger with same service overrides the old one.\nfunc (l *logger) setServiceMethodLogger(service string, ml *MethodLoggerConfig) error {\n\tif _, ok := l.config.Services[service]; ok {\n\t\treturn fmt.Errorf(\"conflicting service rules for service %v found\", service)\n\t}\n\tif l.config.Services == nil {\n\t\tl.config.Services = make(map[string]*MethodLoggerConfig)\n\t}\n\tl.config.Services[service] = ml\n\treturn nil\n}","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/binarylog/binarylog.go#L97-L133","documentation":"Returned by logger.setDefaultMethodLogger when l.config.All is already non-nil (binarylog.go:114-115). The binary log filter config string contains two global ('*') rules. The first '*' sets l.config.All; the second finds it already set and rejects the duplicate. This error propagates through NewLoggerFromConfigString, which logs a warning and returns nil (disabling all binary logging).","triggerScenarios":"Setting GRPC_BINARY_LOG_FILTER to a string containing two global rules, e.g., '*,*' or '*{h:256},*{m:512}'. fillMethodLoggerWithConfigString processes each comma-separated entry; the second '*' triggers setDefaultMethodLogger which finds All already set.","commonSituations":"Accidentally duplicating the global rule when editing the GRPC_BINARY_LOG_FILTER environment variable. Copy-pasting a config that already contained '*'.","solutions":["Remove the duplicate '*' entry from the GRPC_BINARY_LOG_FILTER value","Use only one global rule: '*' or '*{h:256;m:512}'","Validate the config string by splitting on commas and checking for duplicate '*' entries before setting the env var"],"exampleFix":"# before (duplicate global rule)\nexport GRPC_BINARY_LOG_FILTER=\"*,*\"\n\n# after (single global rule)\nexport GRPC_BINARY_LOG_FILTER=\"*\"","handlingStrategy":"validation","validationCode":"// Validate the GRPC_BINARY_LOG_FILTER string for duplicate global rules\nfunc validateBinaryLogConfig(s string) error {\n    if s == \"\" {\n        return nil\n    }\n    globalCount := 0\n    for _, part := range strings.Split(s, \",\") {\n        if strings.HasPrefix(part, \"*\") {\n            globalCount++\n        }\n    }\n    if globalCount > 1 {\n        return fmt.Errorf(\"duplicate global '*' rule in config\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep only one '*' entry in the GRPC_BINARY_LOG_FILTER environment variable","When composing filter strings programmatically, deduplicate global entries","Test the config string in a staging environment before deploying"],"tags":["grpc","binarylog","config","environment-variables","logging"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}