apache/beam · error · IllegalArgumentException

Mutation type not supported.

Error message

Mutation type not supported.

What it means

HBaseRowMutationsCoder.decode reads each Mutation's serialized type byte and reconstructs Put or Delete objects. A stored type byte that maps to neither PUT nor DELETE indicates a corrupted stream or unsupported type, and decode throws IllegalArgumentException('Mutation type not supported.').

Solutions

  1. Ensure RowMutations only contain Put/Delete mutations before they are serialized (see getType enforcement).
  2. Verify all pipeline stages and runners use a consistent Beam version so coder formats match.
  3. Regenerate any persisted test fixtures/state encoded with an incompatible coder format.
  4. If you need Increment/Append, restructure to Put-based updates.

Example fix

// before
RowMutations rm = new RowMutations(row);
rm.add(new Increment(row, CF, QUAL, 1L)); // encoded as unsupported type
// after
rm.add(new Put(row).addColumn(CF, QUAL, Bytes.toBytes(newValue)));
Defensive patterns

Strategy: validation

Validate before calling

public static void validateRowMutations(RowMutations rm) {
  for (Mutation m : rm.getMutations()) {
    if (!(m instanceof Put) && !(m instanceof Delete))
      throw new IllegalArgumentException("unsupported mutation type in RowMutations: " + m.getClass());
  }
}

Type guard

static boolean isDecodable(MutationType type) {
  return type == MutationType.PUT || type == MutationType.DELETE;
}

Try / catch

try {
  RowMutations rm = coder.decode(inStream, context);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Mutation type not supported")) {
    throw new IOException("corrupt/incompatible RowMutations encoding; regenerate data with same Beam version", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Decoding a RowMutations object whose inner mutation has a type byte other than PUT/DELETE — data written by a different/older coder version, corrupted input, or mutations that were Increment/Append smuggled in before serialization elsewhere.

Common situations: Mixing Beam versions where the coder format changed; hand-crafted or corrupted serialized data in state/test fixtures; RowMutations containing Increment/Append built through custom code paths.

Related errors


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

Appendix: source

Thrown at sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseRowMutationsCoder.java:79

    listCoder.encode(value.getMutations(), outStream);
  }

  @Override
  public RowMutations decode(InputStream inStream) throws IOException, IllegalArgumentException {

    byte[] rowKey = byteArrayCoder.decode(inStream);
    List<Mutation> mutations = listCoder.decode(inStream);

    RowMutations rowMutations = new RowMutations(rowKey);
    for (Mutation m : mutations) {
      MutationType type = getType(m);

      if (type == MutationType.PUT) {
        rowMutations.add((Put) m);
      } else if (type == MutationType.DELETE) {
        rowMutations.add((Delete) m);
      } else {
        throw new IllegalArgumentException("Mutation type not supported.");
      }
    }
    return rowMutations;
  }

  @Override
  public List<? extends Coder<?>> getCoderArguments() {
    return Arrays.asList(listCoder, byteArrayCoder);
  }

  /**
   * Coder is always deterministic: 1. {@link RowMutations} maintains equality by row key only,
   * which is asserted equal in this coder 2. Canonical encoding is maintained regardless of object
   * machine or time context
   */
  @Override
  public void verifyDeterministic() {}

View on GitHub (pinned to 12126d8942)