grpc/grpc-java · error · UnsupportedOperationException
Subclass failed to hide static factory
Error message
Subclass failed to hide static factory
What it means
ForwardingServerBuilder is an abstract delegating wrapper around ServerBuilder. Its static forPort() is marked @DoNotCall and exists only to force subclasses to hide it with their own forPort(); calling the base implementation always throws UnsupportedOperationException since the wrapper cannot construct a concrete server builder.
Source
Thrown at api/src/main/java/io/grpc/ForwardingServerBuilder.java:43
import javax.annotation.Nullable;
/**
* A {@link ServerBuilder} that delegates all its builder methods to another builder by default.
*
* @param <T> The type of the subclass extending this abstract class.
* @since 1.34.0
*/
public abstract class ForwardingServerBuilder<T extends ServerBuilder<T>> extends ServerBuilder<T> {
/** The default constructor. */
protected ForwardingServerBuilder() {}
/**
* This method serves to force sub classes to "hide" this static factory.
*/
@DoNotCall("Unsupported")
public static ServerBuilder<?> forPort(int port) {
throw new UnsupportedOperationException("Subclass failed to hide static factory");
}
/**
* Returns the delegated {@code ServerBuilder}.
*/
protected abstract ServerBuilder<?> delegate();
@Override
public T directExecutor() {
delegate().directExecutor();
return thisT();
}
@Override
public T executor(@Nullable Executor executor) {
delegate().executor(executor);
return thisT();
}View on GitHub (pinned to 64daddc1f3)
Solutions
- Call the concrete builder's static factory, e.g. MyServerBuilder.forPort(9090), never ForwardingServerBuilder.forPort
- If you maintain a forwarding subclass, add your own static forPort(int) that builds via your delegate()
- For reflection-based bootstrap, resolve forPort on the concrete subclass Class, not the base wrapper
Example fix
// before ServerBuilder<?> b = ForwardingServerBuilder.forPort(9090); // after ServerBuilder<?> b = MyServerBuilder.forPort(9090); // subclass's own static factory
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the concrete subclass shadows forPort before server bootstrap
if (MyServerBuilder.class.getMethod("forPort", int.class).getDeclaringClass()
== io.grpc.ForwardingServerBuilder.class) {
throw new IllegalStateException("Subclass must shadow forPort");
} Try / catch
try {
serverBuilder = MyServerBuilder.forPort(port);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("Subclass failed to hide static factory")) {
serverBuilder = ServerBuilder.forPort(port);
} else throw e;
} Prevention
- Call forPort on your concrete server builder class only
- When subclassing ForwardingServerBuilder, add your own static forPort immediately
- In config-driven bootstrap, verify the configured builder class actually declares its own static factories
When it happens
Trigger: Calling ForwardingServerBuilder.forPort(port) directly, or through a forwarding subclass that failed to declare its own static forPort(int). Also triggered by reflection or generic server-bootstrap code that resolves forPort on the base wrapper class.
Common situations: Generic server startup code reading a builder class name from configuration and invoking forPort on it when that class is (or extends) ForwardingServerBuilder; custom forwarding server builders missing the shadowing static method; IDE auto-import selecting the base class.
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
- Subclass failed to hide static factory
- Can't set TLS settings for ALTS
- Unsupported operation getPort()
- Not implemented
- At least one credential is required
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/0aa33fd3e2660d21.
Report an issue: GitHub.