grpc/grpc-java · error · UnsupportedOperationException

call forAddress() instead

Error message

call forAddress() instead

What it means

CronetChannelBuilder.forTarget(String) is deliberately unsupported: Cronet channels require a CronetEngine, which the target-string overload cannot supply. The method is annotated @DoNotCall and always throws UnsupportedOperationException to force callers onto forAddress(String, int, CronetEngine).

Source

Thrown at cronet/src/main/java/io/grpc/cronet/CronetChannelBuilder.java:73

  /** BidirectionalStream.Builder factory used for getting the gRPC BidirectionalStream. */
  public static abstract class StreamBuilderFactory {
    public abstract BidirectionalStream.Builder newBidirectionalStreamBuilder(
        String url, BidirectionalStream.Callback callback, Executor executor);
  }

  /** Creates a new builder for the given server host, port and CronetEngine. */
  public static CronetChannelBuilder forAddress(String host, int port, CronetEngine cronetEngine) {
    Preconditions.checkNotNull(cronetEngine, "cronetEngine");
    return new CronetChannelBuilder(host, port, cronetEngine);
  }

  /**
   * Always fails.  Call {@link #forAddress(String, int, CronetEngine)} instead.
   */
  @DoNotCall("Unsupported. Use forAddress(String, int, CronetEngine) instead")
  public static CronetChannelBuilder forTarget(String target) {
    throw new UnsupportedOperationException("call forAddress() instead");
  }

  /**
   * Always fails.  Call {@link #forAddress(String, int, CronetEngine)} instead.
   */
  @DoNotCall("Unsupported. Use forAddress(String, int, CronetEngine) instead")
  public static CronetChannelBuilder forAddress(String name, int port) {
    throw new UnsupportedOperationException("call forAddress(String, int, CronetEngine) instead");
  }

  @Nullable
  private ScheduledExecutorService scheduledExecutorService;

  private final CronetEngine cronetEngine;
  private final ManagedChannelImplBuilder managedChannelImplBuilder;
  private final TransportTracer.Factory transportTracerFactory = TransportTracer.getDefaultFactory();

  private boolean alwaysUsePut = false;

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Replace forTarget(target) with CronetChannelBuilder.forAddress(host, port, cronetEngine)
  2. Construct or obtain a CronetEngine (CronetEngine.Builder(context).build()) and pass it to forAddress
  3. Abstract the transport behind a factory so Cronet-specific creation (engine required) is explicit

Example fix

// before
ManagedChannel ch = CronetChannelBuilder.forTarget("dns:///api.example.com:443").build();
// after
CronetEngine engine = new CronetEngine.Builder(context).build();
ManagedChannel ch = CronetChannelBuilder.forAddress("api.example.com", 443, engine).build();
Defensive patterns

Strategy: fallback

Validate before calling

// Route Cronet channel creation through a factory that requires an engine
ManagedChannel createChannel(String host, int port, CronetEngine engine) {
  java.util.Objects.requireNonNull(engine, "CronetEngine required for CronetChannelBuilder");
  return CronetChannelBuilder.forAddress(host, port, engine).build();
}

Try / catch

try {
  channel = CronetChannelBuilder.forTarget(target); // unsupported
} catch (UnsupportedOperationException e) {
  // migrate: build with forAddress(host, port, cronetEngine)
  channel = CronetChannelBuilder.forAddress(host, port, engine).build();
}

Prevention

When it happens

Trigger: Calling CronetChannelBuilder.forTarget("some-target") or code paths that build a channel via a generic ManagedChannelBuilder.forTarget-style call that resolves to this overload.

Common situations: Shared channel-factory code that builds channels by target string for all transports; migration from OkHttp/Netty builders to Cronet without updating the builder entry point.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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