grpc/grpc-go · error
rls: childPolicyConfigTargetFieldName field is not set in…
Error message
rls: childPolicyConfigTargetFieldName field is not set in service config %+v
What it means
Emitted from (rlsBB).ParseConfig (config.go:174) when ChildPolicyConfigTargetFieldName is the empty string. The RLS balancer injects each RLS-resolved target into the child policy config under this field name (e.g. round_robin uses 'serviceName'), so it is mandatory.
Solutions
- Add childPolicyConfigTargetFieldName to the RLS config object with the field name the chosen child policy expects for its target.
- For round_robin children use 'round_robin' -> target field 'serviceName'; for pick_first use 'serviceName' as well; confirm against the child policy's config struct.
- If the config is xDS-sourced, fix the RouteLookupClusterSpecification on the control plane to include childPolicyConfigTargetFieldName.
Example fix
// before
{ "rls": { "routeLookupConfig": { ... }, "childPolicy": [ { "round_robin": {} } ] } }
// after
{ "rls": {
"routeLookupConfig": { ... },
"childPolicyConfigTargetFieldName": "serviceName",
"childPolicy": [ { "round_robin": {} } ]
} } Defensive patterns
Strategy: validation
Validate before calling
func validateChildTargetField(name string) error {
if strings.TrimSpace(name) == "" {
return errors.New("childPolicyConfigTargetFieldName must be set and non-empty")
}
return nil
} Type guard
func hasChildTargetField(name string) bool { return strings.TrimSpace(name) != "" } Prevention
- Always pair childPolicy with childPolicyConfigTargetFieldName in config templates.
- Document the target field name expected by each candidate child policy (e.g. round_robin -> 'serviceName').
- Add a schema/JSON-Schema check for required fields in your config pipeline.
When it happens
Trigger: The top-level JSON config has no childPolicyConfigTargetFieldName key, or its value is an empty string. The check runs after the RouteLookupConfig proto is parsed but before child-policy validation.
Common situations: A config template that omits the field; an xDS RLS plugin that was not populated with the target field name; copying an example config that used a different schema version where the field was implicit.
Related errors
- rls: invalid childPolicy: entry
- rls: bad control channel service config
- rls: bad RouteLookupConfig proto %+v
- rls: cache_size_bytes must be set to a non-zero value: %+v
- rls: childPolicy config validation failed
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/8b3db3de42a7c8ed.
Report an issue: GitHub.
Appendix: source
Thrown at balancer/rls/config.go:174
rlsProto := &rlspb.RouteLookupConfig{}
if err := m.Unmarshal(cfgJSON.RouteLookupConfig, rlsProto); err != nil {
return nil, fmt.Errorf("rls: bad RouteLookupConfig proto %+v: %v", string(cfgJSON.RouteLookupConfig), err)
}
lbCfg, err := parseRLSProto(rlsProto)
if err != nil {
return nil, err
}
if sc := string(cfgJSON.RouteLookupChannelServiceConfig); sc != "" {
parsed := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(sc)
if parsed.Err != nil {
return nil, fmt.Errorf("rls: bad control channel service config %q: %v", sc, parsed.Err)
}
lbCfg.controlChannelServiceConfig = sc
}
if cfgJSON.ChildPolicyConfigTargetFieldName == "" {
return nil, fmt.Errorf("rls: childPolicyConfigTargetFieldName field is not set in service config %+v", string(c))
}
name, config, err := parseChildPolicyConfigs(cfgJSON.ChildPolicy, cfgJSON.ChildPolicyConfigTargetFieldName)
if err != nil {
return nil, err
}
lbCfg.childPolicyName = name
lbCfg.childPolicyConfig = config
lbCfg.childPolicyTargetField = cfgJSON.ChildPolicyConfigTargetFieldName
return lbCfg, nil
}
func parseRLSProto(rlsProto *rlspb.RouteLookupConfig) (*lbConfig, error) {
// Validations specified on the `grpc_keybuilders` field are performed here.
kbMap, err := keys.MakeBuilderMap(rlsProto)
if err != nil {
return nil, err
}
View on GitHub (pinned to 0c51461d27)