grpc/grpc-go · error
rls_csp: error parsing config
Error message
rls_csp: error parsing config %v: unknown type %T
What it means
ParseClusterSpecifierConfig expected the configuration wrapped as *anypb.Any but received a different concrete proto type (rls.go:58-60). In the xDS protocol all filter and extension configs are transported as Any-wrapped messages, so receiving a bare proto indicates an integration or protocol-layer error.
Solutions
- Ensure the clusterspecifier framework passes *anypb.Any to ParseClusterSpecifierConfig
- Do not manually unwrap Any before calling the parser
- If writing test code, wrap the proto with anypb.New() first
Example fix
// before — passing bare proto
rlsCfg := &rlspb.RouteLookupClusterSpecifier{...}
result, err := rls{}.ParseClusterSpecifierConfig(rlsCfg)
// after — wrap in Any first
anyCfg, _ := anypb.New(rlsCfg)
result, err := rls{}.ParseClusterSpecifierConfig(anyCfg) Defensive patterns
Strategy: type-guard
Type guard
// Ensure the config is *anypb.Any before passing to the parser.
func isAnyProto(msg proto.Message) bool {
_, ok := msg.(*anypb.Any)
return ok
} Prevention
- Always pass *anypb.Any to clusterspecifier parsers — the framework handles unwrapping internally
- Use anypb.New() to wrap protos in test code before calling parser methods
- Do not manually unwrap Any messages before dispatching to plugin parsers
When it happens
Trigger: The clusterspecifier framework dispatches to ParseClusterSpecifierConfig with a proto.Message whose concrete type is not *anypb.Any (e.g. an already-unwrapped RouteLookupClusterSpecifier passed by custom integration or test code).
Common situations: Custom clusterspecifier integration that unwraps Any before dispatching to the plugin; incorrect framework wiring; test code passing a bare proto instead of wrapping it in anypb.New().
Related errors
- rls_csp: error marshaling load balancing config
- rls_csp: error marshaling route lookup config
- rls_csp: error parsing config
- rls_csp: nil configuration message provided
- rls_csp: validation error from rls lb policy parsing
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/df2b7e46195eb861.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/clusterspecifier/rls/rls.go:60
return []string{"type.googleapis.com/grpc.lookup.v1.RouteLookupClusterSpecifier"}
}
// lbConfigJSON is the RLS LB Policies configuration in JSON format.
// RouteLookupConfig will be a raw JSON string from the passed in proto
// configuration, and the other fields will be hardcoded.
type lbConfigJSON struct {
RouteLookupConfig json.RawMessage `json:"routeLookupConfig"`
ChildPolicy []map[string]json.RawMessage `json:"childPolicy"`
ChildPolicyConfigTargetFieldName string `json:"childPolicyConfigTargetFieldName"`
}
func (rls) ParseClusterSpecifierConfig(cfg proto.Message) (clusterspecifier.BalancerConfig, error) {
if cfg == nil {
return nil, fmt.Errorf("rls_csp: nil configuration message provided")
}
m, ok := cfg.(*anypb.Any)
if !ok {
return nil, fmt.Errorf("rls_csp: error parsing config %v: unknown type %T", cfg, cfg)
}
rlcs := new(rlspb.RouteLookupClusterSpecifier)
if err := m.UnmarshalTo(rlcs); err != nil {
return nil, fmt.Errorf("rls_csp: error parsing config %v: %v", cfg, err)
}
rlcJSON, err := protojson.Marshal(rlcs.GetRouteLookupConfig())
if err != nil {
return nil, fmt.Errorf("rls_csp: error marshaling route lookup config: %v: %v", rlcs.GetRouteLookupConfig(), err)
}
lbCfgJSON := &lbConfigJSON{
RouteLookupConfig: rlcJSON, // "JSON form of RouteLookupClusterSpecifier.config" - RLS in xDS Design Doc
ChildPolicy: []map[string]json.RawMessage{
{
"cds_experimental": json.RawMessage(`{"isDynamic":true}`),
},
},
ChildPolicyConfigTargetFieldName: "cluster",View on GitHub (pinned to 0c51461d27)