apache/hadoop · error · IllegalArgumentException

Unexpected HAServiceState:

Error message

Unexpected HAServiceState:

What it means

Inverse of the heartbeat-state converter: maps HAServiceState onto the NNHAStatusHeartbeatProto.State wire enum. Only ACTIVE, STANDBY and OBSERVER are mappable; any other HAServiceState constant (added by a newer or custom build) cannot be serialized and throws IllegalArgumentException.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/PBHelper.java:805

    default:
      throw new IllegalArgumentException("Unexpected HAServiceStateProto:"
          + s);
    }
  }

  public static NNHAStatusHeartbeatProto.State convert(HAServiceState s) {
    if (s == null) {
      return null;
    }
    switch (s) {
    case ACTIVE:
      return NNHAStatusHeartbeatProto.State.ACTIVE;
    case STANDBY:
      return NNHAStatusHeartbeatProto.State.STANDBY;
    case OBSERVER:
      return NNHAStatusHeartbeatProto.State.OBSERVER;
    default:
      throw new IllegalArgumentException("Unexpected HAServiceState:"
          + s);
    }
  }

  public static NNHAStatusHeartbeat convert(NNHAStatusHeartbeatProto s) {
    if (s == null) {
      return null;
    }
    return new NNHAStatusHeartbeat(convert(s.getState()), s.getTxid());
  }

  public static NNHAStatusHeartbeatProto convert(NNHAStatusHeartbeat hb) {
    if (hb == null) {
      return null;
    }
    NNHAStatusHeartbeatProto.Builder builder =
        NNHAStatusHeartbeatProto.newBuilder();
    builder.setState(convert(hb.getState()));

View on GitHub (pinned to 2add963021)

Solutions

  1. Verify a single consistent Hadoop version on the classpath (inspect for duplicate hadoop-hdfs / hadoop-common jars).
  2. Pass only ACTIVE/STANDBY/OBSERVER to the converter.
  3. Upgrade the module containing PBHelper to the release that defines the new state constant.
Defensive patterns

Strategy: validation

Validate before calling

import org.apache.hadoop.ha.HAServiceState;
import java.util.EnumSet;

static final EnumSet<HAServiceState> SERIALIZABLE =
    EnumSet.of(HAServiceState.ACTIVE, HAServiceState.STANDBY,
               HAServiceState.OBSERVER);

if (!SERIALIZABLE.contains(state)) {
  throw new IllegalStateException(
      "HAServiceState " + state + " not supported by this hadoop-hdfs build; "
    + "check for mixed jar versions");
}

Type guard

static boolean isSerializableHAState(HAServiceState s) {
  return s == HAServiceState.ACTIVE
      || s == HAServiceState.STANDBY
      || s == HAServiceState.OBSERVER;
}

Try / catch

try {
  protoBuilder.setState(PBHelper.convert(state));
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("HAServiceState:")) {
    throw new IllegalStateException(
        "Mixed Hadoop versions on classpath; cannot serialize state " + state, e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling PBHelper.convert(HAServiceState) with a constant this build's PBHelper does not know — e.g. newer caller code linked against an older hadoop-hdfs jar, or a custom HAServiceState extension.

Common situations: Duplicate/mismatched hadoop-hdfs jars on the classpath (shaded or vendored copies); partial upgrades where new NN code invokes old serialization helpers; custom HA extensions.

Related errors


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