{"record":{"id":"4458938991f6e980","repo":"apache/hadoop","slug":"failed-to-set-quota-by-storage-type-because-eithe","errorCode":null,"errorMessage":"\"Failed to set quota by storage type because either\" + DFS_QUOTA_BY_STORAGETYPE_ENABLED_KEY + \" is set to \" + fsd.isQuotaByStorageTypeEnabled() + \" or nsQuota value is illegal \" + nsQuota","messagePattern":"\"Failed to set quota by storage type because either\" \\+ DFS_QUOTA_BY_STORAGETYPE_ENABLED_KEY \\+ \" is set to \" \\+ fsd\\.isQuotaByStorageTypeEnabled\\(\\) \\+ \" or nsQuota value is illegal \" \\+ nsQuota","errorType":"exception","errorClass":"UnsupportedActionException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java","lineNumber":344,"sourceCode":"      FSDirectory fsd, INodesInPath iip, long nsQuota,\n      long ssQuota, StorageType type)\n      throws FileNotFoundException, PathIsNotDirectoryException,\n      QuotaExceededException, UnresolvedLinkException,\n      SnapshotAccessControlException, UnsupportedActionException {\n    assert fsd.hasWriteLock();\n    // sanity check\n    if ((nsQuota < 0 && nsQuota != HdfsConstants.QUOTA_DONT_SET &&\n         nsQuota != HdfsConstants.QUOTA_RESET) ||\n        (ssQuota < 0 && ssQuota != HdfsConstants.QUOTA_DONT_SET &&\n          ssQuota != HdfsConstants.QUOTA_RESET)) {\n      throw new IllegalArgumentException(\"Illegal value for nsQuota or \" +\n                                         \"ssQuota : \" + nsQuota + \" and \" +\n                                         ssQuota);\n    }\n    // sanity check for quota by storage type\n    if ((type != null) && (!fsd.isQuotaByStorageTypeEnabled() ||\n        nsQuota != HdfsConstants.QUOTA_DONT_SET)) {\n      throw new UnsupportedActionException(\n          \"Failed to set quota by storage type because either\" +\n          DFS_QUOTA_BY_STORAGETYPE_ENABLED_KEY + \" is set to \" +\n          fsd.isQuotaByStorageTypeEnabled() + \" or nsQuota value is illegal \" +\n          nsQuota);\n    }\n\n    INodeDirectory dirNode =\n        INodeDirectory.valueOf(iip.getLastINode(), iip.getPath());\n    final QuotaCounts oldQuota = dirNode.getQuotaCounts();\n    final long oldNsQuota = oldQuota.getNameSpace();\n    final long oldSsQuota = oldQuota.getStorageSpace();\n    if (dirNode.isRoot() && nsQuota == HdfsConstants.QUOTA_RESET) {\n      nsQuota = HdfsConstants.QUOTA_DONT_SET;\n    } else if (nsQuota == HdfsConstants.QUOTA_DONT_SET) {\n      nsQuota = oldNsQuota;\n    } // a directory inode\n    if (ssQuota == HdfsConstants.QUOTA_DONT_SET) {\n      ssQuota = oldSsQuota;","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java#L326-L362","documentation":"unprotectedSetQuota with a non-null StorageType throws UnsupportedActionException when the NameNode has dfs.quota.by.storage.type.enabled=false, or when the call also carries a namespace quota (nsQuota != QUOTA_DONT_SET) - type quotas are a distinct operation. The message prints the config key with its current state and the offending nsQuota so you can tell which condition fired. The key defaults to true on current Hadoop, but older 2.7/2.8 clusters shipped false.","triggerScenarios":"'hdfs dfsadmin -setSpaceQuota <q> -storageType <type> <dir>' or DistributedFileSystem.setQuotaByStorageType against an NN with the feature disabled; or an internal caller invoking the combined setQuota with both a type and a namespace quota.","commonSituations":"Older Hadoop 2.x clusters where the flag defaulted to false; hardened configs that disable it; custom quota tooling that passes one combined quota struct into the type-quota path.","solutions":["Set dfs.quota.by.storage.type.enabled=true in the NameNode's hdfs-site.xml and restart the NameNode (the flag is read at FSDirectory initialization).","When setting a type quota, pass HdfsConstants.QUOTA_DONT_SET for the namespace quota and set namespace quotas as a separate call.","If the feature must stay disabled, enforce per-type limits outside HDFS or plan an upgrade."],"exampleFix":"<!-- hdfs-site.xml on the NameNode, then restart NN -->\n<property>\n  <name>dfs.quota.by.storage.type.enabled</name>\n  <value>true</value>\n</property>\n\n// and set type quotas in a dedicated call:\ndfs.setQuotaByStorageType(path, StorageType.SSD, quota); // nsQuota stays DONT_SET internally","handlingStrategy":"validation","validationCode":"boolean typeQuotaOn = fs.getConf().getBoolean(\n    DFSConfigKeys.DFS_QUOTA_BY_STORAGETYPE_ENABLED_KEY,\n    DFSConfigKeys.DFS_QUOTA_BY_STORAGETYPE_ENABLED_DEFAULT);\nif (!typeQuotaOn) {\n  throw new IllegalStateException(\n      \"Type quotas disabled on this cluster; enable dfs.quota.by.storage.type.enabled on the NameNode\");\n}\n// set type quota in its own call so nsQuota stays QUOTA_DONT_SET\ndfs.setQuotaByStorageType(path, StorageType.SSD, quota);","typeGuard":null,"tryCatchPattern":"try {\n  dfs.setQuotaByStorageType(path, type, quota);\n} catch (UnsupportedActionException e) {\n  if (e.getMessage().contains(\"quota by storage type\")) {\n    // config disabled on NN or nsQuota leaked into the call: fix config/call shape\n  }\n}","preventionTips":["Client config must mirror the NameNode's flag; verify on the NN config page after restarts.","Never bundle namespace quota values into type-quota calls."],"tags":["hdfs","quota","storage-type","config"],"backgroundTag":"feature-disabled-by-config","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}