grpc/grpc-java · error · UnsupportedOperationException

getChannel() not supported

Error message

getChannel() not supported

What it means

UdsSocket wraps an Android LocalSocket to emulate a java.net.Socket over a Unix Domain Socket. Many java.net.Socket methods have no meaning for LocalSockets; getChannel() (which would return the associated SocketChannel) is one of them and is deliberately implemented to throw UnsupportedOperationException. The UDS transport never uses NIO channels, so there is nothing meaningful to return.

Source

Thrown at android/src/main/java/io/grpc/android/UdsSocket.java:93

      shutdownOutput();
    }
    localSocket.close();
    closed = true;
  }

  @Override
  public void connect(SocketAddress endpoint) throws IOException {
    localSocket.connect(localSocketAddress);
  }

  @Override
  public void connect(SocketAddress endpoint, int timeout) throws IOException {
    localSocket.connect(localSocketAddress, timeout);
  }

  @Override
  public SocketChannel getChannel() {
    throw new UnsupportedOperationException("getChannel() not supported");
  }

  @Override
  public InetAddress getInetAddress() {
    throw new UnsupportedOperationException("getInetAddress() not supported");
  }

  @Override
  public InputStream getInputStream() throws IOException {
    return new FilterInputStream(localSocket.getInputStream()) {
      @Override
      public void close() throws IOException {
        UdsSocket.this.close();
      }
    };
  }

  @Override

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Do not call getChannel() on sockets obtained from the gRPC UDS transport; operate on the stream APIs instead.
  2. Wrap socket access in a capability check: only use getChannel() when socket.getClass() != UdsSocket (or instanceof check fails for the wrapper).
  3. If NIO channel semantics are required, use a TCP channel instead of UdsChannelBuilder.

Example fix

// before
SocketChannel ch = socket.getChannel();
// after
if (socket.getClass().getSimpleName().equals("UdsSocket")) {
  throw new IllegalStateException("UDS sockets have no channel");
}
SocketChannel ch = socket.getChannel();
Defensive patterns

Strategy: type-guard

Type guard

static boolean isUdsSocket(Socket s) {
  return s.getClass().getName().equals("io.grpc.android.UdsSocket");
}

Try / catch

try {
  SocketChannel ch = socket.getChannel();
  useChannel(ch);
} catch (UnsupportedOperationException e) {
  // UDS socket: no NIO channel; use stream-based IO
}

Prevention

When it happens

Trigger: Any code path that calls getChannel() on the Socket instance created by UdsSocketFactory — e.g. library or framework code (connection pools, socket inspectors, NIO helpers) that opportunistically checks for a SocketChannel.

Common situations: Instrumentation or debugging code inspecting the socket; third-party libraries assuming all java.net.Socket subclasses support NIO channels; moving gRPC-over-UDS code into a context that also uses java.nio.

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