grpc/grpc-go · error
rls: childPolicyConfigTargetFieldName field is not set in se
Error message
rls: childPolicyConfigTargetFieldName field is not set in service config %+v
What it means
Returned by rls.ParseConfig (config.go:173-175) when ChildPolicyConfigTargetFieldName is empty. RLS swaps the target field of its child policy config with each looked-up target, so it must know which field name to overwrite (e.g. "target" for pick_first, "endpoint" in xDS). An empty value makes target substitution impossible, so it is required.
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 03255a9237)
Solutions
- Set childPolicyConfigTargetFieldName to the target field name expected by the chosen child policy (commonly "target" for pick_first/round_robin-style policies).
- Ensure the value matches the field name your child policy uses to receive its address/target.
Example fix
// before cfg.ChildPolicyConfigTargetFieldName = "" // after cfg.ChildPolicyConfigTargetFieldName = "target"
Defensive patterns
Strategy: validation
Validate before calling
func validateTargetFieldName(cfg map[string]any) error {
v, _ := cfg["childPolicyConfigTargetFieldName"].(string)
if v == "" {
return errors.New("childPolicyConfigTargetFieldName must be set")
}
return nil
} Type guard
func hasTargetFieldName(cfg map[string]any) bool {
v, _ := cfg["childPolicyConfigTargetFieldName"].(string)
return v != ""
} Prevention
- Always set childPolicyConfigTargetFieldName (typically "target").
- Use a typed config builder that requires the field.
When it happens
Trigger: The RLS service config omits childPolicyConfigTargetFieldName, or sets it to "".
Common situations: Hand-writing RLS config and forgetting the field. Control plane not populating it because the child policy type is ambiguous.
Related errors
- rls: json unmarshal failed for service config %+v: %v
- rls: bad RouteLookupConfig proto %+v: %v
- rls: bad control channel service config %q: %v
- rls: empty lookup_service in route lookup config %+v
- rls: invalid target URI in lookup_service %s
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/8b3db3de42a7c8ed.
Report an issue: GitHub.