{"record":{"id":"837cec548d6c9b67","repo":"grpc/grpc-go","slug":"rls-csp-error-marshaling-route-lookup-config-v","errorCode":null,"errorMessage":"rls_csp: error marshaling route lookup config: %v: %v","messagePattern":"rls_csp: error marshaling route lookup config: (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clusterspecifier/rls/rls.go","lineNumber":69,"sourceCode":"\tChildPolicyConfigTargetFieldName string                       `json:\"childPolicyConfigTargetFieldName\"`\n}\n\nfunc (rls) ParseClusterSpecifierConfig(cfg proto.Message) (clusterspecifier.BalancerConfig, error) {\n\tif cfg == nil {\n\t\treturn nil, fmt.Errorf(\"rls_csp: nil configuration message provided\")\n\t}\n\tm, ok := cfg.(*anypb.Any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"rls_csp: error parsing config %v: unknown type %T\", cfg, cfg)\n\t}\n\trlcs := new(rlspb.RouteLookupClusterSpecifier)\n\n\tif err := m.UnmarshalTo(rlcs); err != nil {\n\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 {","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clusterspecifier/rls/rls.go#L51-L87","documentation":"After successfully unmarshaling the RouteLookupClusterSpecifier, the embedded RouteLookupConfig sub-message could not be serialized to JSON via protojson.Marshal (rls.go:67-69). This typically means RouteLookupConfig is nil or contains data that violates protojson serialization invariants.","triggerScenarios":"rlcs.GetRouteLookupConfig() returns nil or an invalid proto, causing protojson.Marshal to fail when converting the RouteLookupConfig to the JSON form needed for the LB policy configuration.","commonSituations":"xDS server sends a RouteLookupClusterSpecifier with a nil RouteLookupConfig field; required sub-fields of RouteLookupConfig are missing or invalid; proto version differences in the RouteLookupConfig schema between server and client.","solutions":["Ensure the xDS server always includes a non-nil RouteLookupConfig in the RouteLookupClusterSpecifier","Validate the RouteLookupConfig proto for completeness before deploying the xDS config","Check for proto version differences in the RouteLookupConfig schema"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify RouteLookupConfig is non-nil before processing.\nrlcs := new(rlspb.RouteLookupClusterSpecifier)\n_ = anyMsg.UnmarshalTo(rlcs)\nif rlcs.GetRouteLookupConfig() == nil {\n    return fmt.Errorf(\"RouteLookupClusterSpecifier must include a non-nil RouteLookupConfig\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate RouteLookupConfig is non-nil on the xDS server before sending","Use proto validation tools (e.g. protoc-gen-validate) to enforce required fields in RouteLookupConfig","Test RLS configs end-to-end with a local xDS server before production deployment"],"tags":["rls","xds","cluster-specifier","protobuf","marshal"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}