{"record":{"id":"353f541684da95f5","repo":"grpc/grpc-java","slug":"not-implemented-353f54","errorCode":null,"errorMessage":"Not implemented","messagePattern":"Not implemented","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/grpc/ManagedChannel.java","lineNumber":85,"sourceCode":"   *\n   * @return whether the channel is terminated, as would be done by {@link #isTerminated()}.\n   * @since 1.0.0\n   */\n  public abstract boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;\n\n  /**\n   * Gets the current connectivity state. Note the result may soon become outdated.\n   *\n   * <p>Note that the core library did not provide an implementation of this method until v1.6.1.\n   *\n   * @param requestConnection if {@code true}, the channel will try to make a connection if it is\n   *        currently IDLE\n   * @throws UnsupportedOperationException if not supported by implementation\n   * @since 1.1.0\n   */\n  @ExperimentalApi(\"https://github.com/grpc/grpc-java/issues/4359\")\n  public ConnectivityState getState(boolean requestConnection) {\n    throw new UnsupportedOperationException(\"Not implemented\");\n  }\n\n  /**\n   * Registers a one-off callback that will be run if the connectivity state of the channel diverges\n   * from the given {@code source}, which is typically what has just been returned by {@link\n   * #getState}.  If the states are already different, the callback will be called immediately.  The\n   * callback is run in the same executor that runs Call listeners.\n   *\n   * <p>There is an inherent race between the notification to {@code callback} and any call to\n   * {@code getState()}. There is a similar race between {@code getState()} and a call to {@code\n   * notifyWhenStateChanged()}. The state can change during those races, so there is not a way to\n   * see every state transition. \"Transitions\" to the same state are possible, because intermediate\n   * states may not have been observed. The API is only reliable in tracking the <em>current</em>\n   * state.\n   *\n   * <p>Note that the core library did not provide an implementation of this method until v1.6.1.\n   *\n   * @param source the assumed current state, typically just returned by {@link #getState}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/api/src/main/java/io/grpc/ManagedChannel.java#L67-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nConnectivityState s = channel.getState(false); // may throw\n// after\nConnectivityState s;\ntry {\n  s = channel.getState(false);\n} catch (UnsupportedOperationException e) {\n  s = ConnectivityState.IDLE; // implementation does not expose state\n}","handlingStrategy":"try-catch","validationCode":"// Java: assume state support on known implementations\nboolean supportsState = !(channel instanceof my.TestChannel); // or check concrete type before polling","typeGuard":"boolean supportsConnectivityState(ManagedChannel ch) {\n  return ch.getClass().getName().startsWith(\"io.grpc.\") && !(ch instanceof my.TestChannel);\n}","tryCatchPattern":"try {\n  state = channel.getState(false);\n} catch (UnsupportedOperationException e) {\n  state = null; // connectivity state not tracked by this implementation\n}","preventionTips":["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"],"tags":["grpc","java","connectivity","unsupported-operation","channel"],"backgroundTag":"operation-not-supported","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}