apache/hadoop · error · UnsupportedOperationException

Unable to serialize empty EnumSet with no element type provi

Error message

Unable to serialize empty EnumSet with no element type provided.

What it means

write() encodes an empty EnumSet as length 0 plus the element type name string, so the reader can rebuild an empty set of the right enum. If value is empty and elementType is null it throws UnsupportedOperationException — there is nothing to serialize the type from. set() normally prevents this state, so this fires when the invariant is bypassed (e.g. field mutation, subclasses, or a set(emptySet, type) followed by manual nulling).

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/EnumSetWritable.java:146

      E first = (E) ObjectWritable.readObject(in, conf);
      this.value = (EnumSet<E>) EnumSet.of(first);
      for (int i = 1; i < length; i++)
        this.value.add((E) ObjectWritable.readObject(in, conf));
    }
  }

  @Override
  public void write(DataOutput out) throws IOException {
    if (this.value == null) {
      out.writeInt(-1);
      WritableUtils.writeString(out, this.elementType.getName());
    } else {
      Object[] array = this.value.toArray();
      int length = array.length;
      out.writeInt(length);
      if (length == 0) {
        if (this.elementType == null)
          throw new UnsupportedOperationException(
              "Unable to serialize empty EnumSet with no element type provided.");
        WritableUtils.writeString(out, this.elementType.getName());
      }
      for (int i = 0; i < length; i++) {
        ObjectWritable.writeObject(out, array[i], array[i].getClass(), conf);
      }
    }
  }

  /**
   * Returns true if <code>o</code> is an EnumSetWritable with the same value,
   * or both are null.
   */
  @Override
  public boolean equals(Object o) {
    if (o == null) {
      throw new IllegalArgumentException("null argument passed in equal().");
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Always populate via the constructor or set(value, elementType) so the type is captured.
  2. Before writing, guard: if (w.get() == null || ((EnumSet<?>) w.get()).isEmpty()) ensure a type is set — or proactively set(emptySet, MyEnum.class).
  3. Catch UnsupportedOperationException on write and fail the record with field context.

Example fix

// before
EnumSetWritable<Flag> w = ...; // value empty, elementType null
out.write(w); // throws

// after
if (w.get() == null || ((EnumSet<?>) w.get()).isEmpty()) {
  w.set(EnumSet.noneOf(Flag.class), Flag.class);
}
out.write(w);
Defensive patterns

Strategy: validation

Validate before calling

EnumSet<Flag> v = (EnumSet<Flag>) w.get();
if (v == null || v.isEmpty()) {
  w.set(EnumSet.noneOf(Flag.class), Flag.class);
}
out.write(w);

Try / catch

try {
  w.write(out);
} catch (UnsupportedOperationException e) {
  throw new IllegalStateException("EnumSetWritable has empty value and no element type", e);
}

Prevention

When it happens

Trigger: Constructing via a path that skips set()'s guard (reflection/field access setting value to an empty EnumSet with elementType null), then calling write(); subclass of EnumSetWritable that assigns fields directly.

Common situations: Custom serialization frameworks that restore object state field-by-field; test fixtures building writables without constructors; stale forks predating the elementType validation.

Related errors


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