grpc/grpc-java · error · UnsupportedOperationException
Subclass failed to hide static factory
Error message
Subclass failed to hide static factory
What it means
ForwardingChannelBuilder2 is an abstract delegating wrapper around ManagedChannelBuilder. Its static forAddress() factory is marked @DoNotCall and exists only to force subclasses to define their own static forAddress(); invoking the inherited/base one throws UnsupportedOperationException because the wrapper cannot know which concrete builder to construct.
Source
Thrown at api/src/main/java/io/grpc/ForwardingChannelBuilder2.java:51
*
* @param <T> The type of the subclass extending this abstract class.
* @since 1.59.0
*/
public abstract class ForwardingChannelBuilder2<T extends ManagedChannelBuilder<T>>
extends ManagedChannelBuilder<T> {
/**
* The default constructor.
*/
protected ForwardingChannelBuilder2() {
}
/**
* This method serves to force subclasses to "hide" this static factory.
*/
@DoNotCall("Unsupported")
public static ManagedChannelBuilder<?> forAddress(String name, int port) {
throw new UnsupportedOperationException("Subclass failed to hide static factory");
}
/**
* This method serves to force subclasses to "hide" this static factory.
*/
@DoNotCall("Unsupported")
public static ManagedChannelBuilder<?> forTarget(String target) {
throw new UnsupportedOperationException("Subclass failed to hide static factory");
}
/**
* Returns the delegated {@code ManagedChannelBuilder}.
*/
protected abstract ManagedChannelBuilder<?> delegate();
@Override
public T directExecutor() {
delegate().directExecutor();View on GitHub (pinned to 64daddc1f3)
Solutions
- Call the concrete builder's static factory, e.g. MyForwardingBuilder.forAddress(name, port), never ForwardingChannelBuilder2.forAddress
- If you maintain a forwarding subclass, add your own static forAddress(String, int) that delegates to your delegate() implementation
- If resolving reflectively, look up the method on the actual subclass Class, not the base class
Example fix
// before
ManagedChannelBuilder<?> b = ForwardingChannelBuilder2.forAddress("localhost", 8080);
// after
ManagedChannelBuilder<?> b = MyGrpcChannelBuilder.forAddress("localhost", 8080); // subclass's own static factory Defensive patterns
Strategy: validation
Validate before calling
// Never reference the base static factory; verify you are calling the subclass's own
Class<?> concrete = MyGrpcChannelBuilder.class;
if (concrete.getMethod("forAddress", String.class, int.class).getDeclaringClass()
== io.grpc.ForwardingChannelBuilder2.class) {
throw new IllegalStateException("Subclass must shadow forAddress");
} Try / catch
try {
builder = MyGrpcChannelBuilder.forAddress(name, port);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("Subclass failed to hide static factory")) {
builder = ManagedChannelBuilder.forAddress(name, port); // fall back to standard builder
} else throw e;
} Prevention
- Always invoke static factories on the concrete builder class, never on ForwardingChannelBuilder2
- When writing a forwarding builder, immediately add static forAddress/forTarget that mirror the base API
- Avoid reflective lookups of forAddress against the base class
When it happens
Trigger: Calling ForwardingChannelBuilder2.forAddress(host, port) directly instead of the subclass's static factory, or calling it through a subclass that failed to shadow (hide) the static method with its own forAddress implementation. Static methods resolve at compile time on the named class, so referencing the base method always hits this throw.
Common situations: Reflection or generic code that resolves the static factory on ForwardingChannelBuilder2.class rather than the concrete subclass; a custom forwarding builder that forgot to declare its own forAddress; IDE auto-import picking the wrong 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
- Not implemented
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/7ad6c2b51d9a3a1f.
Report an issue: GitHub.