apache/beam · error · IllegalArgumentException

unable to deserialize {description}

Error message

unable to deserialize {description}

What it means

deserializeFromByteArray decodes a byte array produced by serializeToByteArray via ObjectInputStream (Snappy-decompressed). IOException or ClassNotFoundException is rethrown as IllegalArgumentException 'unable to deserialize <description>'. Typical causes are corrupted/truncated bytes or a missing class on the runtime classpath.

Source

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

    }
  }

  /**
   * 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) {
      throw new IllegalArgumentException("unable to deserialize " + description, exn);
    }
  }

  public static <T extends Serializable> T ensureSerializableRoundTrip(T value) {
    T copy = ensureSerializable(value);

    checkState(
        value.equals(copy),
        "Value not equal to original after serialization, indicating that its type may not "
            + "implement serialization or equals correctly.  Before: %s, after: %s",
        value,
        copy);

    return copy;
  }

  public static <T extends Serializable> T ensureSerializable(T value) {
    return clone(value);

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure the bytes were produced by serializeToByteArray (Snappy+ObjectOutputStream) and are not truncated or corrupted in transit/storage.
  2. Make the referenced class available on the runtime classpath and keep serialVersionUID stable across versions.
  3. If classes changed, re-serialize the data with the current classes rather than deserializing old bytes.
  4. Catch IllegalArgumentException around deserializeFromByteArray and treat it as a data-integrity error (re-fetch or recompute the bytes).

Example fix

// before
MyObject o = SerializableUtils.deserializeFromByteArray(bytes, "MyObject");
// after
try {
  MyObject o = SerializableUtils.deserializeFromByteArray(bytes, "MyObject");
} catch (IllegalArgumentException e) {
  throw new DataIntegrityException("corrupt or incompatible serialized data", e);
}
Defensive patterns

Strategy: try-catch

Try / catch

try { T v = SerializableUtils.deserializeFromByteArray(bytes, desc); } catch (IllegalArgumentException e) { throw new DataIntegrityException("corrupt/incompatible payload: " + desc, e); }

Prevention

When it happens

Trigger: Calling deserializeFromByteArray(bytes, description) or clone() with bytes that are not Snappy-serialized Java objects, were serialized with an incompatible class version (InvalidClassException), or reference classes not present at deserialization time.

Common situations: Storing serialized pipeline artifacts across jobs whose classpaths changed, deserializing data written by a different serialization format, class version drift after upgrading dependencies (e.g. serialVersionUID changes).

Related errors


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