grpc/grpc-java · error · UnsupportedOperationException
Not implemented
Error message
Not implemented
What it means
ManagedChannel.getState(boolean) is an ExperimentalApi base method that throws UnsupportedOperationException unless the concrete channel implementation overrides it. It reports the channel's ConnectivityState, optionally requesting a connection. The stub exists so implementations lacking connectivity tracking can simply inherit rather than fake a state.
Source
Thrown at api/src/main/java/io/grpc/ManagedChannel.java:85
*
* @return whether the channel is terminated, as would be done by {@link #isTerminated()}.
* @since 1.0.0
*/
public abstract boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
/**
* Gets the current connectivity state. Note the result may soon become outdated.
*
* <p>Note that the core library did not provide an implementation of this method until v1.6.1.
*
* @param requestConnection if {@code true}, the channel will try to make a connection if it is
* currently IDLE
* @throws UnsupportedOperationException if not supported by implementation
* @since 1.1.0
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4359")
public ConnectivityState getState(boolean requestConnection) {
throw new UnsupportedOperationException("Not implemented");
}
/**
* Registers a one-off callback that will be run if the connectivity state of the channel diverges
* from the given {@code source}, which is typically what has just been returned by {@link
* #getState}. If the states are already different, the callback will be called immediately. The
* callback is run in the same executor that runs Call listeners.
*
* <p>There is an inherent race between the notification to {@code callback} and any call to
* {@code getState()}. There is a similar race between {@code getState()} and a call to {@code
* notifyWhenStateChanged()}. The state can change during those races, so there is not a way to
* see every state transition. "Transitions" to the same state are possible, because intermediate
* states may not have been observed. The API is only reliable in tracking the <em>current</em>
* state.
*
* <p>Note that the core library did not provide an implementation of this method until v1.6.1.
*
* @param source the assumed current state, typically just returned by {@link #getState}View on GitHub (pinned to 64daddc1f3)
Solutions
- Use a standard channel implementation (NettyChannelBuilder/OkHttpChannelBuilder/InProcessChannelBuilder) that overrides getState
- Guard with a capability check and handle the absence of state tracking instead of polling getState
- Catch UnsupportedOperationException and treat the channel as state-unknown, relying on RPC failures instead
- If you implement ManagedChannel yourself, override getState(boolean) and notifyWhenStateChanged to keep them consistent
Example fix
// before
ConnectivityState s = channel.getState(false); // may throw
// after
ConnectivityState s;
try {
s = channel.getState(false);
} catch (UnsupportedOperationException e) {
s = ConnectivityState.IDLE; // implementation does not expose state
} Defensive patterns
Strategy: try-catch
Validate before calling
// Java: assume state support on known implementations boolean supportsState = !(channel instanceof my.TestChannel); // or check concrete type before polling
Type guard
boolean supportsConnectivityState(ManagedChannel ch) {
return ch.getClass().getName().startsWith("io.grpc.") && !(ch instanceof my.TestChannel);
} Try / catch
try {
state = channel.getState(false);
} catch (UnsupportedOperationException e) {
state = null; // connectivity state not tracked by this implementation
} Prevention
- Use standard Netty/OkHttp/InProcess channel implementations that implement the connectivity API
- If you implement ManagedChannel, override both getState and notifyWhenStateChanged
- Avoid hand-rolled channel wrappers when you need connectivity state; rely on RPC status instead
When it happens
Trigger: Calling channel.getState(requestConnection) on a ManagedChannel implementation that has not overridden getState — observed in tests like childChannelConfigurator_passedToResolvingOobChannelNameResolverArgs, oobChannelHasNoChannelCallCredentials, oobChannelWithOobChannelCredsHasChannelCallCredentials, and assertRpcFails, which call it on channels built from builders whose impl does not support it.
Common situations: Using a minimal/custom ManagedChannel (e.g., a test double or a wrapper built via ManagedChannelBuilder with limited features); xDS out-of-band channels in configurations where the underlying builder does not implement connectivity-state APIs; older or third-party transports predating the 1.1.0 connectivity API.
Related errors
- Can't set TLS settings for ALTS
- Not implemented
- Not implemented
- Channel state API is not implemented
- Use forPort(int, ServerCredentials) instead
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/353f541684da95f5.
Report an issue: GitHub.