apache/beam · error · IllegalArgumentException

EnvoyRateLimiterFactory requires EnvoyRateLimiterContext

Error message

EnvoyRateLimiterFactory requires EnvoyRateLimiterContext

What it means

EnvoyRateLimiterFactory.getLimiter(context) only accepts a RateLimiterContext that is an instance of EnvoyRateLimiterContext; any other context implementation is rejected with IllegalArgumentException. The factory needs Envoy-specific data (like descriptors) that a generic context does not carry.

Solutions

  1. Construct an EnvoyRateLimiterContext (via its builder) and pass that to getLimiter().
  2. Use the matching factory for the context type you have, or a factory that accepts generic contexts.
  3. Check the context's runtime class (instanceof EnvoyRateLimiterContext) before wiring it into this factory.

Example fix

// before
RateLimiter limiter = envoyFactory.getLimiter(genericContext); // throws
// after
EnvoyRateLimiterContext ctx = EnvoyRateLimiterContext.builder().setDescriptors(descriptors).build();
RateLimiter limiter = envoyFactory.getLimiter(ctx);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(ctx instanceof EnvoyRateLimiterContext)) {
  throw new IllegalArgumentException("build EnvoyRateLimiterContext for EnvoyRateLimiterFactory");
}

Type guard

static boolean isEnvoyContext(RateLimiterContext ctx) {
  return ctx instanceof EnvoyRateLimiterContext;
}

Try / catch

try {
  RateLimiter limiter = factory.getLimiter(ctx);
} catch (IllegalArgumentException e) {
  ctx = EnvoyRateLimiterContext.builder().setDescriptors(descriptors).build();
  RateLimiter limiter = factory.getLimiter(ctx);
}

Prevention

When it happens

Trigger: Passing a RateLimiterContext created by another factory (or a plain/default context implementation) into EnvoyRateLimiterFactory.getLimiter().

Common situations: Mixing rate limiter factories and contexts in configuration (e.g. a generic context built for a different backend), or after refactoring/swapping the limiter implementation while reusing old context objects.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/a5e617e40182d28d. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/components/src/main/java/org/apache/beam/sdk/io/components/ratelimiter/EnvoyRateLimiterFactory.java:108

    }
    synchronized (this) {
      if (stub == null) {
        RateLimiterClientCache cache = RateLimiterClientCache.getOrCreate(options.getAddress());
        this.clientCache = cache;
        stub = RateLimitServiceGrpc.newBlockingStub(cache.getChannel());
      }
    }
  }

  @VisibleForTesting
  void setStub(RateLimitServiceGrpc.RateLimitServiceBlockingStub stub) {
    this.stub = stub;
  }

  @Override
  public RateLimiter getLimiter(RateLimiterContext context) {
    if (!(context instanceof EnvoyRateLimiterContext)) {
      throw new IllegalArgumentException(
          "EnvoyRateLimiterFactory requires EnvoyRateLimiterContext");
    }
    return new EnvoyRateLimiter(this, (EnvoyRateLimiterContext) context);
  }

  @Override
  public boolean allow(RateLimiterContext context, int permits)
      throws IOException, InterruptedException {
    if (permits == 0) {
      return true;
    }
    if (!(context instanceof EnvoyRateLimiterContext)) {
      throw new IllegalArgumentException(
          "EnvoyRateLimiterFactory requires EnvoyRateLimiterContext, got: "
              + context.getClass().getName());
    }
    checkArgument(permits >= 0, "Permits must be non-negative");
    EnvoyRateLimiterContext envoyContext = (EnvoyRateLimiterContext) context;

View on GitHub (pinned to 12126d8942)