apache/hadoop · critical · IllegalArgumentException

String table bits ${bits} > ${maskBits}

Error message

String table bits ${bits} > ${maskBits}

What it means

SerialNumberManager packs name-to-serial tables (GLOBAL/USER/GROUP/XATTR) into the fsimage string table; the number of tables determines maskBits (this build: 4 tables -> maskBits=3, 29 entry bits). SerialNumberManager.newStringTable(size, bits) throws IllegalArgumentException when the string-table header read from an fsimage carries more mask bits than the running build supports — i.e., the image was written by a Hadoop version with more serial-number tables than this one can decode.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/SerialNumberManager.java:121

    int size = 0;
    for (final SerialNumberManager snm : values) {
      size += snm.size();
    }
    int tableMaskBits = getMaskBits();
    StringTable map = new StringTable(size, tableMaskBits);
    for (final SerialNumberManager snm : values) {
      final int mask = snm.getMask(tableMaskBits);
      for (Entry<Integer, String> entry : snm.entrySet()) {
        map.put(entry.getKey() | mask, entry.getValue());
      }
    }
    return map;
  }

  // returns an empty table for load.
  public static StringTable newStringTable(int size, int bits) {
    if (bits > maskBits) {
      throw new IllegalArgumentException(
        "String table bits " + bits + " > " + maskBits);
    }
    return new StringTable(size, bits);
  }

  public static class StringTable implements Iterable<Entry<Integer, String>> {
    private final int tableMaskBits;
    private final Map<Integer,String> map;

    private StringTable(int size, int loadingMaskBits) {
      this.tableMaskBits = loadingMaskBits;
      this.map = new HashMap<>(size);
    }

    private String get(SerialNumberManager snm, int id) {
      if (tableMaskBits != 0) {
        if (id > maxEntryNumber) {
          throw new IllegalStateException(

View on GitHub (pinned to 2add963021)

Solutions

  1. Read or load the image with the same (or newer) Hadoop version that wrote it — check 'hdfs version' on both sides
  2. If a downgrade is intended, perform it before any checkpoint in the new format exists, or bootstrap the node from a peer/backup that still has an old-format image
  3. As a reader workaround, use the newer distribution's oiv/NN to convert the image, then proceed

Example fix

# before: older binary reading newer image
$ /opt/hadoop-3.2/bin/hdfs oiv -i fsimage_0000000001000 -o dump.xml
java.lang.IllegalArgumentException: String table bits 4 > 3
# after: use the version that wrote the image
$ /opt/hadoop-3.4/bin/hdfs oiv -i fsimage_0000000001000 -o dump.xml
Defensive patterns

Strategy: validation

Validate before calling

// reject cross-version image loads up front
int imageLayout = readImageLayoutVersion(new File(dir, "current/VERSION"));
if (imageLayout < HdfsServerConstants.NAMENODE_LAYOUT_VERSION) {
  throw new IOException("fsimage written by newer layout " + imageLayout
      + "; this build supports " + HdfsServerConstants.NAMENODE_LAYOUT_VERSION
      + " — upgrade this node before loading");
}

Try / catch

try {
  SerialNumberManager.newStringTable(size, bits);
} catch (IllegalArgumentException e) { // "String table bits X > Y"
  throw new IOException("Image from a newer Hadoop build; "
      + "load it with the version that wrote it", e);
}

Prevention

When it happens

Trigger: Loading an fsimage (NameNode startup, 2NN checkpoint merge, offline image viewer) whose serialized string-table 'bits' field exceeds the reader's maskBits constant; happens exactly when a cluster is downgraded or read by older tooling after an image in the newer format was written.

Common situations: Rolling back to an older Hadoop release after a new-version checkpoint was saved; running 'hdfs oiv' from an older distribution against an image produced by a newer one; a standby/2NN on a different version than the active that wrote the image.

Related errors


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