apache/hadoop · error · IOException
No directory is specified.
Error message
No directory is specified.
What it means
parseChangedVolumes builds StorageLocations from the submitted dfs.datanode.data.dir value; if the parse yields zero locations it throws IOException("No directory is specified.") and the live volume refresh (refreshVolumes, driven by reconfiguring dfs.datanode.data.dir) aborts before touching any volume. The value must be a comma-separated list with at least one valid [TYPE]scheme://path entry.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java:1158
List<StorageLocation> unchangedLocations = Lists.newArrayList();
}
/**
* Parse the new DFS_DATANODE_DATA_DIR value in the configuration to detect
* changed volumes.
* @param newVolumes a comma separated string that specifies the data volumes.
* @return changed volumes.
* @throws IOException if none of the directories are specified in the
* configuration, or the storage type of a directory is changed.
*/
@VisibleForTesting
ChangedVolumes parseChangedVolumes(String newVolumes) throws IOException {
Configuration conf = new Configuration();
conf.set(DFS_DATANODE_DATA_DIR_KEY, newVolumes);
List<StorageLocation> newStorageLocations = getStorageLocations(conf);
if (newStorageLocations.isEmpty()) {
throw new IOException("No directory is specified.");
}
// Use the existing storage locations from the current conf
// to detect new storage additions or removals.
Map<String, StorageLocation> existingStorageLocations = new HashMap<>();
for (StorageLocation loc : getStorageLocations(getConf())) {
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();) {View on GitHub (pinned to 2add963021)
Solutions
- Resubmit with at least one valid entry — the value is the complete desired volume set, e.g. [DISK]file:///data/dn1
- To remove volumes, list only the directories to KEEP; never an empty string
- To retire the very last volume, decommission the DataNode instead of live-removing it
Example fix
// before $ hdfs dfsadmin -reconfig datanode dn1:9867 start ... dfs.datanode.data.dir= // => IOException: No directory is specified. // after $ hdfs dfsadmin -reconfig datanode dn1:9867 start ... dfs.datanode.data.dir=[DISK]file:///data/dn1
Defensive patterns
Strategy: validation
Validate before calling
Configuration c = new Configuration(false);
c.set(DFS_DATANODE_DATA_DIR_KEY, newVolumes);
if (DataNode.getStorageLocations(c).isEmpty()) {
throw new IllegalArgumentException("new dfs.datanode.data.dir parses to zero locations");
} Try / catch
try {
dn.refreshVolumes? // internal; externally: reconfigure dfs.datanode.data.dir
} catch (ReconfigurationException e) {
if (String.valueOf(e.getCause()).contains("No directory is specified")) { /* resubmit full desired volume list */ }
} Prevention
- The reconfig value is the complete desired volume set — never submit an empty string
- Fail template rendering when the data-dir variable is undefined instead of emitting empty
- To drop the last volume, decommission the DataNode
When it happens
Trigger: Submitting dfs.datanode.data.dir="", ",", whitespace, or entries that all fail URI parsing via 'hdfs dfsadmin -reconfig datanode ... start' or the reconfig JMX API; an unexpanded ${DATANODE_DIRS} placeholder renders to a single invalid location string.
Common situations: Ansible/Chef templates rendering an empty string when a variable is undefined; a 'remove volumes' attempt that blanks the field instead of listing the surviving dirs; CM/Ambari UI fields accidentally cleared before apply.
Related errors
- Not a valid Boolean value for {property} in reconfSlowPeerPa
- Not a valid Boolean value for {property}
- Changing storage type is not allowed.
- Attempt to remove all volumes.
- Invalid value configured for dfs.datanode.failed.volumes.tol
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/0ea7e3b9d922df0a.
Report an issue: GitHub.