{"record":{"id":"9db1a1865971bd2f","repo":"apache/hadoop","slug":"storagelocation-specified-for-storage-directory-s","errorCode":null,"errorMessage":"StorageLocation specified for storage directory {sd} is null","messagePattern":"StorageLocation specified for storage directory (.+?) is null","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsVolumeImpl.java","lineNumber":162,"sourceCode":"   * Per-volume worker pool that processes new blocks to cache.\n   * The maximum number of workers per volume is bounded (configurable via\n   * dfs.datanode.fsdatasetcache.max.threads.per.volume) to limit resource\n   * contention.\n   */\n  protected ThreadPoolExecutor cacheExecutor;\n\n  FsVolumeImpl(FsDatasetImpl dataset, String storageID, StorageDirectory sd,\n      FileIoProvider fileIoProvider, Configuration conf) throws IOException {\n    // outside tests, usage created in ReservedSpaceCalculator.Builder\n    this(dataset, storageID, sd, fileIoProvider, conf, null);\n  }\n\n  FsVolumeImpl(FsDatasetImpl dataset, String storageID, StorageDirectory sd,\n      FileIoProvider fileIoProvider, Configuration conf, DF usage)\n      throws IOException {\n\n    if (sd.getStorageLocation() == null) {\n      throw new IOException(\"StorageLocation specified for storage directory \" +\n          sd + \" is null\");\n    }\n    this.dataset = dataset;\n    this.storageID = storageID;\n    this.reservedForReplicas = new AtomicLong(0L);\n    this.storageLocation = sd.getStorageLocation();\n    this.currentDir = sd.getCurrentDir();\n    this.storageType = storageLocation.getStorageType();\n    this.configuredCapacity = -1;\n    this.usage = usage;\n    if (this.usage != null) {\n      reserved = new ReservedSpaceCalculator.Builder(conf)\n          .setUsage(this.usage).setStorageType(storageType)\n          .setDir(currentDir != null ? currentDir.getParent() : \"NULL\").build();\n      boolean fixedSizeVolume = conf.getBoolean(\n          DFSConfigKeys.DFS_DATANODE_FIXED_VOLUME_SIZE_KEY,\n          DFSConfigKeys.DFS_DATANODE_FIXED_VOLUME_SIZE_DEFAULT);\n      if (fixedSizeVolume) {","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsVolumeImpl.java#L144-L180","documentation":"FsVolumeImpl's constructor refuses a StorageDirectory whose getStorageLocation() is null: every volume must know the URI it was configured from (parsed from dfs.datanode.data.dir). A null location means storage parsing produced a directory object without a usable location - malformed configuration, cloned/legacy layout, or direct StorageDirectory construction in tests.","triggerScenarios":"dfs.datanode.data.dir containing an entry that failed URI parsing but still yielded a StorageDirectory; StorageDirectory objects built from a VERSION file without a location (test/utility paths); storage dirs transplanted from a downgrade.","commonSituations":"Typos or empty entries in dfs.datanode.data.dir; incorrect storage-type tags like [SSD]/[RAM_DISK]; custom tools creating StorageDirectory instances; edge cases after format or rollback.","solutions":["Check dfs.datanode.data.dir: every entry must be a valid URI such as [disk]file:///dfs/dn or [SSD]file:///... - remove empty or malformed entries.","Verify parsed storage locations in the DN startup log (or hdfs datanode startup text).","If tests build StorageDirectory directly, supply a StorageLocation wrapping a URI when constructing.","Format or roll back cleanly rather than hand-editing in_use.lock/VERSION to point at new dirs."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (sd.getStorageLocation() == null) {\n  // reject this storage directory before building a volume\n  throw new IOException(\"StorageDirectory without location: \" + sd);\n}","typeGuard":null,"tryCatchPattern":"try {\n  volume = new FsVolumeImpl(dataset, storageID, sd, fileIoProvider, conf);\n} catch (IOException e) {\n  // skip this directory; DN continues with remaining volumes if tolerated\n}","preventionTips":["Validate every dfs.datanode.data.dir entry as a URI with a storage-type tag before startup.","Never hand-edit VERSION or in_use.lock to redirect storage directories.","In tests, always construct StorageDirectory with an explicit StorageLocation."],"tags":["hdfs","datanode","storage","configuration","volume"],"backgroundTag":"hdfs-storage-directory-misconfigured","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}