grpc/grpc-java · error · RemoteException
BinderProxy#transact(code, FLAG_ONEWAY) returned false
Error message
BinderProxy#transact(code, FLAG_ONEWAY) returned false
What it means
OneWayBinderProxy.transact sends a FLAG_ONEWAY binder transaction; per the Android binder contract a oneway transact should never return false. If BinderProxy#transact nevertheless reports false, the proxy throws a RemoteException so the caller treats it as an ordinary transport-layer error.
Source
Thrown at binder/src/main/java/io/grpc/binder/internal/OneWayBinderProxy.java:116
/**
* Returns the wrapped {@link IBinder} for the purpose of calling methods other than {@link
* IBinder#transact(int, Parcel, Parcel, int)}.
*/
public IBinder getDelegate() {
return delegate;
}
static class OutOfProcessImpl extends OneWayBinderProxy {
OutOfProcessImpl(IBinder iBinder) {
super(iBinder);
}
@Override
public void transact(int code, ParcelHolder data) throws RemoteException {
if (!transactAndRecycleParcel(code, data.release())) {
// This cannot happen (see g/android-binder/c/jM4NvS234Rw) but, just in case, let the caller
// handle it along with all the other possible transport-layer errors.
throw new RemoteException("BinderProxy#transact(" + code + ", FLAG_ONEWAY) returned false");
}
}
}
protected boolean transactAndRecycleParcel(int code, Parcel data) throws RemoteException {
try {
return delegate.transact(code, data, null, IBinder.FLAG_ONEWAY);
} finally {
data.recycle();
}
}
static class InProcessImpl extends OneWayBinderProxy {
private final SerializingExecutor executor;
InProcessImpl(IBinder binder, Executor executor) {
super(binder);
this.executor = new SerializingExecutor(executor);View on GitHub (pinned to 64daddc1f3)
Solutions
- Catch the RemoteException in the RPC caller and let gRPC's transport error handling fail/retry the call as with any transport error.
- Retry the transaction; if it repeats, rebind to the remote service (the binder object may be stale).
- If reproducible, report it upstream (see the referenced binder bug thread) since it violates the oneway transact contract.
Defensive patterns
Strategy: try-catch
Try / catch
try {
proxy.transact(code, data);
} catch (RemoteException e) {
// treat as transport error: rebind to service and/or retry
} Prevention
- Handle all RemoteExceptions from binder calls uniformly as transport errors.
- Rebind to the remote service on repeated failures.
- Keep binder/driver tooling up to date on test devices.
When it happens
Trigger: A FLAG_ONEWAY transaction through BinderProxy#transact returns false - an unexpected binder-driver outcome documented as practically impossible, but guarded here so callers can handle it with all other transport errors.
Common situations: Binder driver anomalies or kernel/device-specific issues during a oneway call between an Android app and a remote service; practically never hit in normal code paths.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- call forAddress(AndroidComponentAddress, Context) instead
- call forAddress() instead
- TLS not supported in BinderServer
- The transport factory is closed.
- TARGET_ANDROID_USER NameResolver.Arg requires SDK_INT >= R a
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/a35d34b7035890d2.
Report an issue: GitHub.