{"record":{"id":"eeae4e1a1dca9459","repo":"grpc/grpc-go","slug":"rls-csp-error-marshaling-load-balancing-config-v","errorCode":null,"errorMessage":"rls_csp: error marshaling load balancing config %v: %v","messagePattern":"rls_csp: error marshaling load balancing config (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clusterspecifier/rls/rls.go","lineNumber":83,"sourceCode":"\t\treturn nil, fmt.Errorf(\"rls_csp: error parsing config %v: %v\", cfg, err)\n\t}\n\trlcJSON, err := protojson.Marshal(rlcs.GetRouteLookupConfig())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rls_csp: error marshaling route lookup config: %v: %v\", rlcs.GetRouteLookupConfig(), err)\n\t}\n\tlbCfgJSON := &lbConfigJSON{\n\t\tRouteLookupConfig: rlcJSON, // \"JSON form of RouteLookupClusterSpecifier.config\" - RLS in xDS Design Doc\n\t\tChildPolicy: []map[string]json.RawMessage{\n\t\t\t{\n\t\t\t\t\"cds_experimental\": json.RawMessage(`{\"isDynamic\":true}`),\n\t\t\t},\n\t\t},\n\t\tChildPolicyConfigTargetFieldName: \"cluster\",\n\t}\n\n\trawJSON, err := json.Marshal(lbCfgJSON)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rls_csp: error marshaling load balancing config %v: %v\", lbCfgJSON, err)\n\t}\n\n\trlsBB := balancer.Get(internal.RLSLoadBalancingPolicyName)\n\tif rlsBB == nil {\n\t\treturn nil, fmt.Errorf(\"RLS LB policy not registered\")\n\t}\n\tif _, err = rlsBB.(balancer.ConfigParser).ParseConfig(rawJSON); err != nil {\n\t\treturn nil, fmt.Errorf(\"rls_csp: validation error from rls lb policy parsing: %v\", err)\n\t}\n\n\treturn clusterspecifier.BalancerConfig{{internal.RLSLoadBalancingPolicyName: lbCfgJSON}}, nil\n}\n","sourceCodeStart":65,"sourceCodeEnd":96,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clusterspecifier/rls/rls.go#L65-L96","documentation":"The internally constructed lbConfigJSON struct could not be serialized via encoding/json.Marshal (rls.go:81-83). The struct contains a json.RawMessage field (RouteLookupConfig bytes from protojson), so a marshal failure means those bytes are not valid JSON.","triggerScenarios":"json.Marshal(lbCfgJSON) fails because the RouteLookupConfig json.RawMessage produced by the preceding protojson.Marshal contains bytes that encoding/json rejects as invalid JSON.","commonSituations":"Extremely rare — protojson.Marshal succeeded but produced output that encoding/json considers invalid; indicates a bug in the protobuf library or corrupted proto state. Effectively an internal/library error rather than a configuration issue.","solutions":["This is likely a google.golang.org/protobuf library bug — report it with the RouteLookupConfig proto that triggered it","Check for outdated or mismatched google.golang.org/protobuf versions in go.mod","Inspect the lbCfgJSON.RouteLookupConfig bytes for anomalies"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate that protojson output is valid JSON before re-marshaling.\nif !json.Valid(rlcJSON) {\n    return fmt.Errorf(\"protojson produced invalid JSON for RouteLookupConfig\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep google.golang.org/protobuf dependency up to date","Report reproducible marshal failures to the protobuf team with the triggering proto","Pin protobuf library versions in go.mod to avoid unexpected behavior changes"],"tags":["rls","xds","cluster-specifier","internal","marshal"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}