grpc/grpc-java · info · UnsupportedOperationException

Unsupported operation setKeepAlive()

Error message

Unsupported operation setKeepAlive()

What it means

setKeepAlive() controls TCP SO_KEEPALIVE, which does not exist for Unix domain sockets. UdsSocket's override throws UnsupportedOperationException because the wrapped Android LocalSocket cannot honor it.

Solutions

  1. Remove setKeepAlive calls for UDS channels — gRPC keepalive is configured on the channel/ClientCall, not the raw socket, and TCP keepalive does not apply to UDS
  2. Use gRPC's built-in keepalive channel options if liveness detection is needed
  3. Guard shared socket-config code to skip keep-alive for UdsSocket instances

Example fix

// before
socket.setKeepAlive(true);
// after
if (!(socket instanceof io.grpc.android.UdsSocket)) {
  socket.setKeepAlive(true);
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean supportsKeepAlive = !(socket instanceof io.grpc.android.UdsSocket);

Type guard

static boolean supportsTcpKeepAlive(java.net.Socket s) { return !(s instanceof io.grpc.android.UdsSocket); }

Try / catch

try { socket.setKeepAlive(on); } catch (UnsupportedOperationException e) { /* not applicable on UDS */ }

Prevention

When it happens

Trigger: Calling UdsSocket.setKeepAlive(true/false) directly, or shared channel/socket configuration code that enables keep-alive on every socket it touches (common with gRPC keepalive setups).

Common situations: Configuring gRPC TCP keepalive parameters (keepAliveTime/keepAliveTimeout) and additionally poking the raw socket; copying TCP channel setup code to a 'uds:' channel.

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

Appendix: source

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

  @Override
  public synchronized boolean isInputShutdown() {
    return inputShutdown;
  }

  @Override
  public synchronized boolean isOutputShutdown() {
    return outputShutdown;
  }

  @Override
  public void sendUrgentData(int data) {
    throw new UnsupportedOperationException("Unsupported operation sendUrgentData()");
  }

  @Override
  public void setKeepAlive(boolean on) {
    throw new UnsupportedOperationException("Unsupported operation setKeepAlive()");
  }

  @Override
  public void setOOBInline(boolean on) {
    throw new UnsupportedOperationException("Unsupported operation setOOBInline()");
  }

  @Override
  public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
    throw new UnsupportedOperationException("Unsupported operation setPerformancePreferences()");
  }

  @Override
  public void setReceiveBufferSize(int size) throws SocketException {
    try {
      localSocket.setReceiveBufferSize(size);
    } catch (IOException e) {
      throw toSocketException(e);

View on GitHub (pinned to 64daddc1f3)