grpc/grpc-go · error
rls: json unmarshal failed for child policy config %q: %v
Error message
rls: json unmarshal failed for child policy config %q: %v
What it means
Before RLS can ask the child policy to validate its config, it json.Unmarshal's the raw child config bytes into a map[string]json.RawMessage to inject the target field name. If those bytes are not valid JSON, this unmarshal fails and the error (including the underlying json error) is returned.
Source
Thrown at balancer/rls/config.go:310
for name, rawCfg = range config {
}
builder := balancer.Get(name)
if builder == nil {
continue
}
parser, ok := builder.(balancer.ConfigParser)
if !ok {
return "", nil, fmt.Errorf("rls: childPolicy %q with config %q does not support config parsing", name, string(rawCfg))
}
// To validate child policy configs we do the following:
// - unmarshal the raw JSON bytes of the child policy config into a map
// - add an entry with key set to `target_field_name` and a dummy value
// - marshal the map back to JSON and parse the config using the parser
// retrieved previously
var childConfig map[string]json.RawMessage
if err := json.Unmarshal(rawCfg, &childConfig); err != nil {
return "", nil, fmt.Errorf("rls: json unmarshal failed for child policy config %q: %v", string(rawCfg), err)
}
childConfig[targetFieldName], _ = json.Marshal(dummyChildPolicyTarget)
jsonCfg, err := json.Marshal(childConfig)
if err != nil {
return "", nil, fmt.Errorf("rls: json marshal failed for child policy config {%+v}: %v", childConfig, err)
}
if _, err := parser.ParseConfig(jsonCfg); err != nil {
return "", nil, fmt.Errorf("rls: childPolicy config validation failed: %v", err)
}
return name, childConfig, nil
}
return "", nil, fmt.Errorf("rls: invalid childPolicy config: no supported policies found in %+v", childPolicies)
}
func convertDuration(d *durationpb.Duration) (time.Duration, error) {
if d == nil {
return 0, nil
}View on GitHub (pinned to 03255a9237)
Solutions
- Run the full service config through a JSON validator (jq ., jsonschema) before deploying.
- Fix the specific syntax error reported in the trailing %v (it names line/position).
- Generate configs programmatically with encoding/json rather than string concatenation.
Example fix
// before
"childPolicy": [{ "round_robin": { 'shard': 1 } }]
// after
"childPolicy": [{ "round_robin": { "shard": 1 } }] Defensive patterns
Strategy: validation
Validate before calling
func validateChildPolicyJSON(childPolicy []map[string]json.RawMessage) error {
for i, entry := range childPolicy {
for name, raw := range entry {
var m map[string]json.RawMessage
if err := json.Unmarshal(raw, &m); err != nil {
return fmt.Errorf("childPolicy[%d].%s: invalid JSON: %w", i, name, err)
}
}
}
return nil
} Prevention
- Validate the whole service config with jq before deploying.
- Generate configs with encoding/json instead of string templates.
- Reject single-quoted JSON or trailing commas in your config lint.
When it happens
Trigger: The value side of a childPolicy entry is malformed JSON: trailing comma, unquoted string, single quotes, or a stray character. E.g. [{"round_robin": {broken}}].
Common situations: Hand-editing service config JSON; YAML-to-JSON tools producing non-strict output; concatenating config fragments without re-validating; copy-paste introducing smart quotes.
Related errors
- rls: stale_age is set, but max_age is not in route lookup co
- rls: cache_size_bytes must be set to a non-zero value: %+v
- rls: invalid childPolicy: entry %v does not contain exactly
- rls: childPolicy %q with config %q does not support config p
- rls: childPolicy config validation failed: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/910784ce66605db6.
Report an issue: GitHub.