apache/hadoop · error · IOException

Changing storage type is not allowed.

Error message

Changing storage type is not allowed.

What it means

During refreshVolumes, every new location that matches an existing StorageDirectory is compared against the previously configured location for the same normalized URI; if the storage type differs (oldLocation.getStorageType() != newLocation.getStorageType()), HDFS throws IOException("Changing storage type is not allowed.") because a live volume cannot be retyped in place. No volumes are modified when this fires.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java:1183

      existingStorageLocations.put(loc.getNormalizedUri().toString(), loc);
    }

    ChangedVolumes results = new ChangedVolumes();
    results.newLocations.addAll(newStorageLocations);

    for (Iterator<Storage.StorageDirectory> it = storage.dirIterator();
         it.hasNext(); ) {
      Storage.StorageDirectory dir = it.next();
      boolean found = false;
      for (Iterator<StorageLocation> newLocationItr =
           results.newLocations.iterator(); newLocationItr.hasNext();) {
        StorageLocation newLocation = newLocationItr.next();
        if (newLocation.matchesStorageDirectory(dir)) {
          StorageLocation oldLocation = existingStorageLocations.get(
              newLocation.getNormalizedUri().toString());
          if (oldLocation != null &&
              oldLocation.getStorageType() != newLocation.getStorageType()) {
            throw new IOException("Changing storage type is not allowed.");
          }
          // Update the unchanged locations as this location
          // from the new conf is really not a new one.
          newLocationItr.remove();
          results.unchangedLocations.add(newLocation);
          found = true;
          break;
        }
      }

      // New conf doesn't have the storage location which available in
      // the current storage locations. Add to the deactivateLocations list.
      if (!found) {
        LOG.info("Deactivation request received for active volume: {}",
            dir.getRoot());
        results.deactivateLocations.add(
            StorageLocation.parse(dir.getRoot().toString()));
      }

View on GitHub (pinned to 2add963021)

Solutions

  1. Split into two reconfigs: first submit the value WITHOUT the location (it deactivates), then re-add it with the new type prefix in a second reconfig
  2. Or stop the DataNode, update dfs.datanode.data.dir, and restart — the startup path re-reads types cleanly
  3. Double-check every bracketed prefix; a missing prefix means DISK

Example fix

# before (single reconfig, rejected)
dfs.datanode.data.dir=[SSD]file:///data/dn1,[DISK]file:///data/dn2
# after step 1: drop dn1
dfs.datanode.data.dir=[DISK]file:///data/dn2
# after step 2: re-add with the new type
dfs.datanode.data.dir=[SSD]file:///data/dn1,[DISK]file:///data/dn2
Defensive patterns

Strategy: validation

Validate before calling

Map<String, StorageType> oldByUri = new HashMap<>();
for (StorageLocation l : DataNode.getStorageLocations(currentConf))
  oldByUri.put(l.getNormalizedUri().toString(), l.getStorageType());
for (StorageLocation l : newLocations) {
  StorageType t = oldByUri.get(l.getNormalizedUri().toString());
  if (t != null && t != l.getStorageType())
    throw new IllegalArgumentException("cannot retype " + l + " from " + t);
}

Try / catch

catch (ReconfigurationException e) {
  if (String.valueOf(e.getCause()).contains("Changing storage type")) {
    // split into remove-then-re-add with the new type, in two separate reconfigs
  }
}

Prevention

When it happens

Trigger: Live-reconfiguring dfs.datanode.data.dir where an existing path's bracketed type prefix changes: [DISK]file:///data/dn1 -> [SSD]file:///data/dn1, or dropping the prefix entirely (default DISK) where the old config had [ARCHIVE]/[SSD], or vice versa.

Common situations: Tiering a hot volume to SSD/NVMe; unifying per-host configs where one host had explicit type prefixes and the shared template omits them; typos in type names that silently become DISK and collide with an old typed entry.

Related errors


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