{"record":{"id":"fb90f5c7672adcf4","repo":"apache/hadoop","slug":"storage-policy-name-is-empty","errorCode":null,"errorMessage":"Storage policy name is empty.","messagePattern":"Storage policy name is empty\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java","lineNumber":940,"sourceCode":"      String snapshotPath =\n          cp.createSnapshot(fullpath, snapshotName.getValue());\n      final String js = JsonUtil.toJsonString(\n          org.apache.hadoop.fs.Path.class.getSimpleName(), snapshotPath);\n      return Response.ok(js).type(MediaType.APPLICATION_JSON).build();\n    }\n    case RENAMESNAPSHOT: {\n      validateOpParams(op, oldSnapshotName, snapshotName);\n      cp.renameSnapshot(fullpath, oldSnapshotName.getValue(),\n          snapshotName.getValue());\n      return Response.ok().type(MediaType.APPLICATION_OCTET_STREAM).build();\n    }\n    case DISALLOWSNAPSHOT: {\n      cp.disallowSnapshot(fullpath);\n      return Response.ok().type(MediaType.APPLICATION_OCTET_STREAM).build();\n    }\n    case SETSTORAGEPOLICY: {\n      if (policyName.getValue() == null) {\n        throw new IllegalArgumentException(\"Storage policy name is empty.\");\n      }\n      cp.setStoragePolicy(fullpath, policyName.getValue());\n      return Response.ok().type(MediaType.APPLICATION_OCTET_STREAM).build();\n    }\n    case SATISFYSTORAGEPOLICY:\n      cp.satisfyStoragePolicy(fullpath);\n      return Response.ok().type(MediaType.APPLICATION_OCTET_STREAM).build();\n\n    case ENABLEECPOLICY:\n      validateOpParams(op, ecpolicy);\n      cp.enableErasureCodingPolicy(ecpolicy.getValue());\n      return Response.ok().type(MediaType.APPLICATION_OCTET_STREAM).build();\n    case DISABLEECPOLICY:\n      validateOpParams(op, ecpolicy);\n      cp.disableErasureCodingPolicy(ecpolicy.getValue());\n      return Response.ok().type(MediaType.APPLICATION_OCTET_STREAM).build();\n    case SETECPOLICY:\n      validateOpParams(op, ecpolicy);","sourceCodeStart":922,"sourceCodeEnd":958,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java#L922-L958","documentation":"Thrown by the NameNode-side WebHDFS PUT handler (put() covers op=SETSTORAGEPOLICY) when the request carries no storagepolicy query parameter. The handler checks policyName.getValue() == null and rejects the call with IllegalArgumentException before the filesystem is touched; WebHDFS surfaces it to the REST client as an HTTP 400 RemoteException reading 'Storage policy name is empty.'.","triggerScenarios":"PUT /webhdfs/v1/<path>?op=SETSTORAGEPOLICY without a storagepolicy=<name> parameter. Typical with hand-written curl scripts, gateway/filter layers (HttpFS proxies, Knox) that drop unknown query parameters, and custom clients ported from DistributedFileSystem.setStoragePolicy() that forget the REST-side parameter.","commonSituations":"Scripts that copy one op= URL template for every operation; API wrappers that build query strings from a generic map which omits null values; version drift where a client library stopped appending the parameter; automation applying policies right after path creation.","solutions":["Add the parameter to the request: ...&op=SETSTORAGEPOLICY&storagepolicy=WARM (valid built-ins: HOT, WARM, COLD, ALL_SSD, ONE_SSD, LAZY_PERSIST, or a user-defined policy name)","List the cluster's policy names first with GET /webhdfs/v1/?op=GETSTORAGEPOLICIES and copy one exactly","If the policy is custom, confirm it exists and is enabled via hdfs dfsadmin -listStoragePolicies / -addStoragePolicies","Dump the request actually sent (curl -v) to check whether a proxy stripped the parameter"],"exampleFix":"# before\nPUT /webhdfs/v1/data?op=SETSTORAGEPOLICY&user.name=hdfs\n# 400 ... java.lang.IllegalArgumentException: Storage policy name is empty.\n\n# after\nPUT /webhdfs/v1/data?op=SETSTORAGEPOLICY&storagepolicy=ALL_SSD&user.name=hdfs","handlingStrategy":"validation","validationCode":"static String setStoragePolicyUrl(String path, String policy) {\n  if (policy == null || policy.isEmpty()) {\n    throw new IllegalArgumentException(\"storagepolicy query parameter is required for op=SETSTORAGEPOLICY\");\n  }\n  return \"/webhdfs/v1\" + path + \"?op=SETSTORAGEPOLICY&storagepolicy=\"\n      + URLEncoder.encode(policy, StandardCharsets.UTF_8);\n}","typeGuard":null,"tryCatchPattern":"try {\n  httpPut(setStoragePolicyUrl(path, policy));\n} catch (IOException e) { // HTTP 400 -> RemoteException: java.lang.IllegalArgumentException\n  if (e.getMessage() != null && e.getMessage().contains(\"Storage policy name is empty\")) {\n    throw new IllegalStateException(\"storagepolicy parameter missing from request URL\", e);\n  }\n  throw e;\n}","preventionTips":["Centralize WebHDFS URL building in one helper per op with required-parameter asserts","Unit-test every op URL the client can produce, asserting per-op required parameters survive to the final string","Log the full outgoing URL at DEBUG to catch gateways that strip query parameters"],"tags":["webhdfs","hdfs","storage-policy","rest-api","missing-parameter","query-parameter"],"backgroundTag":"missing-required-parameter","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}