apache/beam · error · IllegalArgumentException

unable to serialize

Error message

unable to serialize {value}

What it means

serializeToByteArray serializes a Serializable object with ObjectOutputStream (Snappy-compressed). Any IOException during writing is rethrown as IllegalArgumentException 'unable to serialize <value>'. This usually means the object graph contains a non-serializable field (NotSerializableException is an IOException subclass) rather than an I/O problem.

Solutions

  1. Inspect the cause (NotSerializableException names the offending class) and make that class implement Serializable.
  2. Mark non-serializable fields transient and reconstruct them lazily (or in readObject/readResolve).
  3. Remove the non-serializable capture from lambdas/anonymous classes; pass only serializable data or look up resources at runtime.
  4. For third-party types, wrap them in a custom Serializable adapter or serialize only the data needed to rebuild them.

Example fix

// before
new DoFn<String, String>() { String helper = someNonSerializableHelper; ... }
// after
class MyFn extends DoFn<String, String> {
  transient Helper helper; // rebuilt in @Setup
  @Setup void setup() { helper = new Helper(); }
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!java.io.Serializable.class.isInstance(value)) { throw new IllegalArgumentException(value.getClass() + " is not Serializable"); }

Type guard

static <T> boolean isSerializable(T v) { return v instanceof java.io.Serializable; }

Try / catch

try { byte[] b = SerializableUtils.serializeToByteArray(value); } catch (IllegalArgumentException e) { LOG.error("non-serializable: {}", e.getCause()); throw e; }

Prevention

When it happens

Trigger: Calling SerializableUtils.serializeToByteArray(value) or clone(value) where value (or a nested field/lambda capture) does not implement Serializable, e.g. capturing a DoFn-unfriendly object in an anonymous class.

Common situations: Passing lambdas or anonymous inner classes that capture non-serializable objects (connection handles, builders, non-serializable library types) into Beam transforms that clone/serialize them.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/25812e95c80ec74f. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/SerializableUtils.java:59

@SuppressWarnings({
  "nullness", // TODO(https://github.com/apache/beam/issues/20497)
  "rawtypes"
})
public class SerializableUtils {
  /**
   * Serializes the argument into an array of bytes, and returns it.
   *
   * @throws IllegalArgumentException if there are errors when serializing
   */
  public static byte[] serializeToByteArray(Serializable value) {
    try {
      ByteArrayOutputStream buffer = new ByteArrayOutputStream();
      try (ObjectOutputStream oos = new ObjectOutputStream(new SnappyOutputStream(buffer))) {
        oos.writeObject(value);
      }
      return buffer.toByteArray();
    } catch (IOException exn) {
      throw new IllegalArgumentException("unable to serialize " + value, exn);
    }
  }

  /**
   * Deserializes an object from the given array of bytes, e.g., as serialized using {@link
   * #serializeToByteArray}, and returns it.
   *
   * @throws IllegalArgumentException if there are errors when deserializing, using the provided
   *     description to identify what was being deserialized
   */
  public static Object deserializeFromByteArray(byte[] encodedValue, String description) {
    try {
      try (ObjectInputStream ois =
          new ContextualObjectInputStream(
              new SnappyInputStream(new ByteArrayInputStream(encodedValue)))) {
        return ois.readObject();
      }
    } catch (IOException | ClassNotFoundException exn) {

View on GitHub (pinned to 12126d8942)