grpc/grpc-java · error · UnsupportedOperationException

ClientTransportServersBuilder is required, use a constructor

Error message

ClientTransportServersBuilder is required, use a constructor

What it means

ServerImplBuilder is the base class for concrete server builders (e.g. NettyServerBuilder). Its static inherited forPort(int) method cannot construct a transport-agnostic server, so it's annotated @DoNotCall and always throws UnsupportedOperationException, instructing users to use a concrete constructor.

Source

Thrown at core/src/main/java/io/grpc/internal/ServerImplBuilder.java:66

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;

/**
 * Default builder for {@link io.grpc.Server} instances, for usage in Transport implementations.
 */
public final class ServerImplBuilder extends ServerBuilder<ServerImplBuilder> {

  private static final Logger log = Logger.getLogger(ServerImplBuilder.class.getName());

  @DoNotCall("ClientTransportServersBuilder is required, use a constructor")
  public static ServerBuilder<?> forPort(int port) {
    throw new UnsupportedOperationException(
        "ClientTransportServersBuilder is required, use a constructor");
  }

  // defaults
  private static final ObjectPool<? extends Executor> DEFAULT_EXECUTOR_POOL =
      SharedResourcePool.forResource(GrpcUtil.SHARED_CHANNEL_EXECUTOR);
  private static final HandlerRegistry DEFAULT_FALLBACK_REGISTRY = new DefaultFallbackRegistry();
  private static final DecompressorRegistry DEFAULT_DECOMPRESSOR_REGISTRY =
      DecompressorRegistry.getDefaultInstance();
  private static final CompressorRegistry DEFAULT_COMPRESSOR_REGISTRY =
      CompressorRegistry.getDefaultInstance();
  private static final long DEFAULT_HANDSHAKE_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(120);

  // mutable state
  final InternalHandlerRegistry.Builder registryBuilder =
      new InternalHandlerRegistry.Builder();
  final List<ServerTransportFilter> transportFilters = new ArrayList<>();
  final List<ServerInterceptor> interceptors = new ArrayList<>();

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Use a concrete transport builder: NettyServerBuilder.forPort(port) or NettyServerBuilder.forPort with grpc-netty dependency
  2. Add the transport dependency (grpc-netty or grpc-netty-shaded) so ServerBuilder.forPort can find a provider via META-INF/services
  3. Replace generic ServerBuilder.forPort calls in framework code with the transport-specific constructor

Example fix

// before
Server server = ServerBuilder.forPort(8080).build(); // no transport provider
// after
Server server = NettyServerBuilder.forPort(8080).build();
Defensive patterns

Strategy: type-guard

Validate before calling

if (b instanceof ServerImplBuilder) { throw new IllegalStateException("No transport provider; add grpc-netty and use NettyServerBuilder"); }

Type guard

static boolean hasTransportProvider(ServerBuilder<?> b) { return !(b instanceof io.grpc.internal.ServerImplBuilder); }

Try / catch

try { server = ServerBuilder.forPort(port).build(); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("ClientTransportServersBuilder is required")) { server = NettyServerBuilder.forPort(port).build(); } else throw e; }

Prevention

When it happens

Trigger: Calling ServerBuilder.forPort(port) generically (e.g. via reflection or generic code paths) when the resolved builder is ServerImplBuilder rather than a concrete transport builder like NettyServerBuilder.forPort().

Common situations: Using ServerBuilder.forPort() without grpc-netty(-shaded) on the classpath so the service loader finds no provider and falls back to ServerImplBuilder; generic framework code calling ServerBuilder.forPort directly.

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/323bfeb7343b39ee. Report an issue: GitHub.