apache/hadoop · error · IllegalStateException

Incompatible layout {} (expected {})

Error message

Incompatible layout {} (expected {})

What it means

ImageWriter compares the layout version of a freshly formatted NNStorage (NNStorage.newNamespaceInfo(), derived from the Hadoop jars on the classpath) against the LAYOUT_VERSION constant the tool was compiled with. A difference means this fs2img build cannot emit an fsimage the target Namenode code understands, so it refuses immediately with IllegalStateException showing found vs expected. It is a guard against producing an unusable image.

Source

Thrown at hadoop-tools/hadoop-fs2img/src/main/java/org/apache/hadoop/hdfs/server/namenode/ImageWriter.java:132

  }

  @SuppressWarnings("unchecked")
  public ImageWriter(Options opts) throws IOException {
    final OutputStream out;
    if (null == opts.outStream) {
      FileSystem fs = opts.outdir.getFileSystem(opts.getConf());
      outfs = (fs instanceof LocalFileSystem)
          ? ((LocalFileSystem)fs).getRaw()
          : fs;
      Path tmp = opts.outdir;
      if (!outfs.mkdirs(tmp)) {
        throw new IOException("Failed to create output dir: " + tmp);
      }
      try (NNStorage stor = new NNStorage(opts.getConf(),
          Arrays.asList(tmp.toUri()), Arrays.asList(tmp.toUri()))) {
        NamespaceInfo info = NNStorage.newNamespaceInfo();
        if (info.getLayoutVersion() != LAYOUT_VERSION) {
          throw new IllegalStateException("Incompatible layout " +
              info.getLayoutVersion() + " (expected " + LAYOUT_VERSION + ")");
        }
        // set the cluster id, if given
        if (opts.clusterID.length() > 0) {
          info.setClusterID(opts.clusterID);
        }
        // if block pool id is given
        if (opts.blockPoolID.length() > 0) {
          info.setBlockPoolID(opts.blockPoolID);
        }

        stor.format(info);
        blockPoolID = info.getBlockPoolID();
      }
      outdir = new Path(tmp, "current");
      out = outfs.create(new Path(outdir, "fsimage_0000000000000000000"));
    } else {
      outdir = null;

View on GitHub (pinned to 2add963021)

Solutions

  1. Run fs2img from the same Hadoop distribution/version as the target Namenode.
  2. Rebuild the imaging tool against the matching Hadoop version and retry.
  3. Use the found/expected pair in the message to confirm the mismatch before swapping jars.

Example fix

# before: tool bundled with old jars
java -cp fs2img-shaded.jar ... 

# after: run with the cluster's own hadoop
hadoop fs2img -o file:///img /data   # uses target cluster's Hadoop version
Defensive patterns

Strategy: validation

Validate before calling

// Before generating, confirm the tool's layout matches the running Hadoop jars
NamespaceInfo info = NNStorage.newNamespaceInfo();
if (info.getLayoutVersion() != LAYOUT_VERSION) {
  throw new IllegalStateException("fs2img/NN layout mismatch: rebuild the tool against this Hadoop version");
}

Try / catch

try {
  new ImageWriter(opts);
} catch (IllegalStateException e) {
  if (e.getMessage().startsWith("Incompatible layout")) {
    // run fs2img from the target cluster's Hadoop distribution, not a mismatched bundle
  }
}

Prevention

When it happens

Trigger: Running an fs2img jar built against one Hadoop release with runtime jars (or a target cluster) from another release whose Namenode layout version differs - e.g. a custom bundled tool with an old hadoop-client against an upgraded cluster.

Common situations: Shaded/standalone fs2img tooling pinning an old Hadoop version; cluster upgraded but the imaging toolchain not rebuilt; mixing jars from different hadoop distributions on one classpath.

Related errors


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