grpc/grpc-go · error

rls_csp: nil configuration message provided

Error message

rls_csp: nil configuration message provided

What it means

Returned by the RLS cluster specifier plugin's ParseClusterSpecifierConfig when the proto.Message argument is nil. The clusterspecifier framework calls this with the Any-wrapped config from an xDS RouteAction.cluster_specifier_plugin; a nil here means the plugin was invoked without a config body.

Source

Thrown at internal/xds/clusterspecifier/rls/rls.go:56

type rls struct{}

func (rls) TypeURLs() []string {
	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{
			{

View on GitHub (pinned to 03255a9237)

Solutions

  1. On the management server, ensure the RLS cluster_specifier_plugin entry has a fully populated RouteLookupClusterSpecifier config.
  2. Validate the route configuration before publishing (e.g. with the control plane's validator).
  3. If hit during testing of a custom cluster specifier flow, make sure you pass a non-nil proto.Message.
Defensive patterns

Strategy: validation

Type guard

func isNonNilClusterCfg(cfg proto.Message) bool { return cfg != nil }

Prevention

When it happens

Trigger: An xDS route configuration references the RLS cluster specifier plugin (type URL grpc.lookup.v1.RouteLookupClusterSpecifier) but supplies no configuration message, or the framework hands nil through a malformed code path.

Common situations: Server-side route config that declares an RLS cluster_specifier_plugin with an empty/missing config, or a control-plane bug that drops the typed_struct/any body.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/92995a119b31712d. Report an issue: GitHub.