grpc/grpc-java · error · IllegalArgumentException

CEL expression references unsupported named function:

Error message

CEL expression references unsupported named function: 

What it means

Final branch of checkAllowedReferences: when a named function reference is neither allowlisted via overload IDs nor the explicitly-rejected string() conversion, it is rejected as an unsupported named function. This error names the exact function so developers know what is not available in the xDS CEL sandbox.

Source

Thrown at xds/src/main/java/io/grpc/xds/internal/matcher/CelCommon.java:128

                || ALLOWED_OVERLOAD_ID_PREFIX_PATTERN.matcher(id).matches()) {
              allowed = true;
              break;
            }
          }
          if (!allowed) {
            throw new IllegalArgumentException(
                "CEL expression references unknown function with overload IDs: "
                    + ref.overloadIds());
          }
        } else {
          // Standard conversion functions (like string(x)) are named in the AST.
          // We must explicitly reject 'string' here since it's disabled in the environment.
          if (name.equals("string")) {
            throw new IllegalArgumentException(
                "CEL expression references unknown function with overload IDs: "
                    + ref.overloadIds());
          }
          throw new IllegalArgumentException(
              "CEL expression references unsupported named function: " + name);
        }
      }
    }
  }
}

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Rewrite the expression using only the allowed core functions (comparison, size, membership, has())
  2. Move unsupported logic into code that decides routing before/around the matcher
  3. Consult the CEL environment declaration for the exact allowlist of functions
  4. Split complex expressions into simpler allowed checks combined with && / ||

Example fix

// before
CEL: timestamp(request.headers['x-ts']) > now
// after — no timestamp function; do a string/size-based check instead
CEL: has(request.headers['x-ts']) && request.headers['x-ts'] != ''
Defensive patterns

Strategy: try-catch

Validate before calling

if (!Set.of("size","has","matches","contains","startsWith","endsWith").containsAll(extractFunctionNames(celSource))) {
  throw new IllegalArgumentException("CEL uses unsupported named function");
}

Try / catch

try {
  CelCommon.checkAllowedReferences(ast);
} catch (IllegalArgumentException e) {
  log.error("Unsupported CEL function: {}", e.getMessage());
}

Prevention

When it happens

Trigger: A CEL expression calls any named function outside the allowed set (e.g., timestamp(), dyn(), extensions, or user-declared functions from another environment) — any name other than the permitted patterns.

Common situations: Porting CEL policies from other products (Envoy, OPA-style CEL) that enable richer function sets; relying on CEL extensions not enabled in gRPC-XDS matchers.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/7545c6a433fe418b. Report an issue: GitHub.