{"record":{"id":"5ae15a295950568e","repo":"grpc/grpc-go","slug":"rls-json-unmarshal-failed-for-service-config-v","errorCode":null,"errorMessage":"rls: json unmarshal failed for service config %+v: %v","messagePattern":"rls: json unmarshal failed for service config %\\+v: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/rls/config.go","lineNumber":152,"sourceCode":"//\t   - `cache_size_bytes` field must have a value greater than 0, and if its\n//\t     value is greater than 5M, we cap it at 5M\n//\n//\t- routeLookupChannelServiceConfig:\n//\t  - if specified, must parse as valid service config\n//\n//\t- childPolicy:\n//\t  - must find a valid child policy with a valid config\n//\n//\t- childPolicyConfigTargetFieldName:\n//\t  - must be set and non-empty\nfunc (rlsBB) ParseConfig(c json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {\n\tif logger.V(2) {\n\t\tlogger.Infof(\"Received JSON service config: %v\", pretty.ToJSON(c))\n\t}\n\n\tcfgJSON := &lbConfigJSON{}\n\tif err := json.Unmarshal(c, cfgJSON); err != nil {\n\t\treturn nil, fmt.Errorf(\"rls: json unmarshal failed for service config %+v: %v\", string(c), err)\n\t}\n\n\tm := protojson.UnmarshalOptions{DiscardUnknown: true}\n\trlsProto := &rlspb.RouteLookupConfig{}\n\tif err := m.Unmarshal(cfgJSON.RouteLookupConfig, rlsProto); err != nil {\n\t\treturn nil, fmt.Errorf(\"rls: bad RouteLookupConfig proto %+v: %v\", string(cfgJSON.RouteLookupConfig), err)\n\t}\n\tlbCfg, err := parseRLSProto(rlsProto)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif sc := string(cfgJSON.RouteLookupChannelServiceConfig); sc != \"\" {\n\t\tparsed := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(sc)\n\t\tif parsed.Err != nil {\n\t\t\treturn nil, fmt.Errorf(\"rls: bad control channel service config %q: %v\", sc, parsed.Err)\n\t\t}\n\t\tlbCfg.controlChannelServiceConfig = sc","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/balancer/rls/config.go#L134-L170","documentation":"Returned by rls.ParseConfig (config.go:150-153) when json.Unmarshal of the RLS service config into lbConfigJSON fails. lbConfigJSON has four raw fields (RouteLookupConfig, RouteLookupChannelServiceConfig, ChildPolicy, ChildPolicyConfigTargetFieldName); the top-level JSON must be a well-formed object containing these. The %+v is the raw JSON string and %v the json error.","triggerScenarios":"The RLS service config string is syntactically invalid JSON, or a field that must be an object/array is the wrong JSON type, causing unmarshal to fail before any proto parsing.","commonSituations":"Hand-authoring the RLS service config JSON and introducing a syntax error. Control plane emitting a malformed RLS config. Version skew where a new/required field changed type.","solutions":["Read the %v json error (it gives line/offset) and fix the JSON at that point.","Run the config through a JSON validator before applying it.","Ensure routeLookupConfig is a JSON object (protojson form) and childPolicy is an array of policy objects.","If from xDS, inspect the RLS Cluster config the control plane produced."],"exampleFix":"// before\nraw := `{ \"routeLookupConfig\": {...}, \"childPolicy\": [...] }` // syntax error somewhere\n\n// after: validate with encoding/json; ensure valid object with the four expected fields","handlingStrategy":"validation","validationCode":"func validateRLSJSON(raw []byte) error {\n    var c struct {\n        RouteLookupConfig                json.RawMessage `json:\"routeLookupConfig\"`\n        ChildPolicyConfigTargetFieldName string          `json:\"childPolicyConfigTargetFieldName\"`\n    }\n    if err := json.Unmarshal(raw, &c); err != nil {\n        return fmt.Errorf(\"rls JSON invalid: %w\", err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate RLS service config JSON in CI before deploying.","Generate the config from typed structs and marshal, rather than hand-writing strings.","Diff against a known-good RLS config when debugging."],"tags":["go","grpc","load-balancing","rls","config","json"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}