grpc/grpc-go · error

RLS call throttled at client side

Error message

RLS call throttled at client side

What it means

Thrown by StringMatcherFromProto when a StringMatcher's SafeRegex match pattern fails to compile as a Go RE2 regular expression via regexp.Compile. The xDS StringMatcher SafeRegex variant expects an RE2-compatible pattern; if the pattern contains unsupported syntax (e.g., backreferences, lookahead) or is malformed, compilation fails. The error wraps the offending pattern for diagnosis.

Source

Thrown at balancer/rls/picker.go:40

	"errors"
	"fmt"
	"strings"
	"sync/atomic"
	"time"

	"google.golang.org/grpc/balancer"
	"google.golang.org/grpc/balancer/rls/internal/keys"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/connectivity"
	estats "google.golang.org/grpc/experimental/stats"
	internalgrpclog "google.golang.org/grpc/internal/grpclog"
	rlspb "google.golang.org/grpc/internal/proto/grpc_lookup_v1"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
)

var (
	errRLSThrottled = errors.New("RLS call throttled at client side")

	// Function to compute data cache entry size.
	computeDataCacheEntrySize = dcEntrySize
)

// exitIdler wraps the only method on the BalancerGroup that the picker calls.
type exitIdler interface {
	ExitIdleOne(id string)
}

// rlsPicker selects the subConn to be used for a particular RPC. It does not
// manage subConns directly and delegates to pickers provided by child policies.
type rlsPicker struct {
	// The keyBuilder map used to generate RLS keys for the RPC. This is built
	// by the LB policy based on the received ServiceConfig.
	kbm keys.BuilderMap
	// Endpoint from the user's original dial target. Used to set the `host_key`
	// field in `extra_keys`.

View on GitHub (pinned to 0c51461d27)

Solutions

  1. Test the regex against Go's regexp package: if regexp.MustCompile(pattern) fails locally, the pattern is incompatible — rewrite it to RE2 syntax.
  2. Remove backreferences, lookahead, and lookbehind constructs; RE2 only supports leftmost-longest matching without them.
  3. If the pattern is used for simple matching, consider switching the StringMatcher to exact, prefix, suffix, or contains variants which do not require regex compilation.

Example fix

// before (control plane config with RE2-incompatible regex):
string_matcher:
  safe_regex:
    regex: "^(foo)\1$"  // backreference - unsupported by RE2

// after:
string_matcher:
  safe_regex:
    regex: "^foofoo$"  // equivalent, RE2-compatible
Defensive patterns

Strategy: validation

Validate before calling

// Pre-compile regex patterns to verify RE2 compatibility before sending them in xDS:
func validateSafeRegex(pattern string) error {
    if _, err := regexp.Compile(pattern); err != nil {
        return fmt.Errorf("regex %q is not RE2-compatible: %w", pattern, err)
    }
    return nil
}

// Usage before building the StringMatcher proto:
for _, p := range policies {
    for _, perm := range p.GetPermissions() {
        if h := perm.GetHeader(); h != nil {
            if sm := h.GetStringMatch(); sm != nil {
                if sr := sm.GetSafeRegex(); sr != nil {
                    if err := validateSafeRegex(sr.GetRegex()); err != nil {
                        return err
                    }
                }
            }
        }
    }
}

Prevention

When it happens

Trigger: An xDS resource (route match, RBAC header matcher, path matcher, authenticated principal matcher) specifies a string matcher with safe_regex whose regex field is syntactically invalid or uses PCRE-only features not supported by Go's RE2 engine. For example, a pattern like '(?P<name>...)\k<name>' (named backreference) will fail because RE2 does not support backreferences.

Common situations: Patterns ported from Envoy's default regex engine that have wider syntax support. A control plane that passes user-supplied regex strings without validation. Patterns with unescaped special characters or mismatched parentheses. An RE2-incompatible construct like \1 backreferences or lookbehind (?<=...).

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/639d77e09985bc04. Report an issue: GitHub.