apache/hadoop · error · IllegalArgumentException

Cannot wrap ${class}

Error message

Cannot wrap ${class}

What it means

RpcWritable.wrap adapts an object for IPC serialization and accepts exactly four shapes: an RpcWritable, a shaded-protobuf Message (ProtobufWrapper), an unshaded-protobuf Message (ProtobufWrapperLegacy), or a Writable (WritableWrapper). Anything else yields IllegalArgumentException("Cannot wrap <class>") — the object handed to the RPC layer for writing is not serializable by any supported engine.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/RpcWritable.java:59

 * Anything marked public is solely for access by SaslRpcClient
 */
// note
@InterfaceAudience.Private
public abstract class RpcWritable implements Writable {

  static RpcWritable wrap(Object o) {
    if (o instanceof RpcWritable) {
      return (RpcWritable)o;
    } else if (o instanceof Message) {
      // hadoop shaded protobuf
      return new ProtobufWrapper((Message)o);
    } else if (ProtobufWrapperLegacy.isUnshadedProtobufMessage(o)) {
      // unshaded protobuf
      return new ProtobufWrapperLegacy(o);
    } else if (o instanceof Writable) {
      return new WritableWrapper((Writable)o);
    }
    throw new IllegalArgumentException("Cannot wrap " + o.getClass());
  }

  // don't support old inefficient Writable methods.
  @Override
  public final void readFields(DataInput in) throws IOException {
    throw new UnsupportedOperationException();
  }
  @Override
  public final void write(DataOutput out) throws IOException {
    throw new UnsupportedOperationException();
  }

  // methods optimized for reduced intermediate byte[] allocations.
  abstract void writeTo(ResponseBuffer out) throws IOException;
  abstract <T> T readFrom(ByteBuffer bb) throws IOException;

  // adapter for Writables. Used for RPC_BUILTIN calls.
  static class WritableWrapper extends RpcWritable {

View on GitHub (pinned to 2add963021)

Solutions

  1. Change the offending protocol method's payload type to a Writable implementation or a protobuf-generated Message compiled with the same (shaded) runtime Hadoop uses.
  2. Read the class name in the message — it names the exact object that failed to wrap, pointing at the specific protocol method.
  3. Verify generated protobuf classes come from the same protoc/runtime generation as the deployed Hadoop (shaded org.apache.hadoop.thirdparty.protobuf vs unshaded com.google.protobuf).

Example fix

// before
public interface MyProtocol {
  String getStatus(); // Cannot wrap class java.lang.String
}
// after
public interface MyProtocol {
  StatusResponseProto getStatus(); // protobuf Message (or a Writable implementation)
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean ipcSerializable(Object o) {
  return o instanceof Writable
      || o instanceof org.apache.hadoop.thirdparty.protobuf.Message
      || o instanceof com.google.protobuf.Message;
}

// before putting a response on the wire:
if (!ipcSerializable(payload)) {
  throw new IllegalArgumentException(
      "protocol payload not IPC-serializable: " + payload.getClass());
}

Type guard

static boolean isIpcSerializable(Object o) {
  return o instanceof Writable
      || o instanceof org.apache.hadoop.thirdparty.protobuf.Message
      || o instanceof com.google.protobuf.Message;
}

Prevention

When it happens

Trigger: A protocol method whose request/response type is a plain Java type (String, Map, POJO) that is neither Writable nor a protobuf-generated Message; protobuf classes compiled against a protobuf runtime that matches neither the shaded nor unshaded branch; passing a response object of the wrong type through custom RPC plumbing.

Common situations: Hand-designed RPC protocols that ignore the Writable/protobuf constraint; mixing shaded and unshaded generated protobuf classes in one classpath; convenience methods accidentally left in a protocol interface; protobuf version upgrades leaving stale generated classes.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/7bcedc0a103c526d. Report an issue: GitHub.