grpc/grpc-java · error · UnsupportedOperationException

TLS not supported in BinderServer

Error message

TLS not supported in BinderServer

What it means

BinderServerBuilder.useTransportSecurity(File certChain, File privateKey) overrides the ServerBuilder TLS setup but the binder transport does not support TLS — it communicates over Android Binder IPC, where transport security is provided by the OS process boundary. The method always throws UnsupportedOperationException('TLS not supported in BinderServer').

Source

Thrown at binder/src/main/java/io/grpc/binder/BinderServerBuilder.java:141

   * @return this
   */
  public BinderServerBuilder securityPolicy(ServerSecurityPolicy securityPolicy) {
    internalBuilder.setServerSecurityPolicy(securityPolicy);
    return this;
  }

  /** Sets the policy for inbound parcelable objects. */
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/8022")
  public BinderServerBuilder inboundParcelablePolicy(
      InboundParcelablePolicy inboundParcelablePolicy) {
    internalBuilder.setInboundParcelablePolicy(inboundParcelablePolicy);
    return this;
  }

  /** Always fails. TLS is not supported in BinderServer. */
  @Override
  public BinderServerBuilder useTransportSecurity(File certChain, File privateKey) {
    throw new UnsupportedOperationException("TLS not supported in BinderServer");
  }

  /**
   * Builds a {@link Server} according to this builder's parameters and stores its listening {@link
   * IBinder} in the {@link IBinderReceiver} passed to {@link #forAddress(AndroidComponentAddress,
   * IBinderReceiver)}.
   *
   * @return the new Server
   */
  @Override
  public Server build() {
    // Since we install a final interceptor here, we need to ensure we're only built once.
    checkState(!isBuilt, "BinderServerBuilder can only be used to build one server instance.");
    isBuilt = true;
    // We install the security interceptor last, so it's closest to the transport.
    BinderTransportSecurity.installAuthInterceptor(this);
    internalBuilder.setExecutorPool(serverImplBuilder.getExecutorPool());
    return super.build();

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Remove the useTransportSecurity call — Binder IPC is already protected by the Android process sandbox
  2. If TLS is a hard requirement, run the server over the standard NettyServerBuilder instead of the binder transport

Example fix

// before
BinderServerBuilder.forAddress(addr, receiver)
    .useTransportSecurity(new File("cert.pem"), new File("key.pem"))
    .build();
// after
BinderServerBuilder.forAddress(addr, receiver).build();
Defensive patterns

Strategy: validation

Validate before calling

if (tlsEnabled && serverBuilder instanceof BinderServerBuilder) {
  throw new IllegalArgumentException("TLS is not supported for binder servers");
}

Try / catch

try {
  return builder.build();
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("TLS")) { log.warn("TLS unsupported on binder transport; using Binder IPC security"); }
  throw e;
}

Prevention

When it happens

Trigger: Calling useTransportSecurity(certChain, privateKey) (or the File-less overload) on a BinderServerBuilder before build().

Common situations: Copy-pasted server setup that enables TLS for every ServerBuilder; attempting to 'harden' a binder server with TLS out of habit from INET servers.

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