{"record":{"id":"396bb52689511134","repo":"apache/hadoop","slug":"operation-0-invalid-path-1-must-be","errorCode":null,"errorMessage":"Operation [{0}], invalid path [{1}], must be '/'","messagePattern":"Operation \\[(.+?)\\], invalid path \\[(.+?)\\], must be '/'","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":400,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java","lineNumber":200,"sourceCode":"   *\n   * @throws IOException thrown if an IO error occurred. Thrown exceptions are\n   * handled by {@link HttpFSExceptionProvider}.\n   * @throws FileSystemAccessException thrown if a FileSystemAccess related error occurred. Thrown\n   * exceptions are handled by {@link HttpFSExceptionProvider}.\n   */\n  private FileSystem createFileSystem(UserGroupInformation ugi)\n      throws IOException, FileSystemAccessException {\n    String hadoopUser = ugi.getShortUserName();\n    FileSystemAccess fsAccess = HttpFSServerWebApp.get().get(FileSystemAccess.class);\n    Configuration conf = HttpFSServerWebApp.get().get(FileSystemAccess.class).getFileSystemConfiguration();\n    FileSystem fs = fsAccess.createFileSystem(hadoopUser, conf);\n    FileSystemReleaseFilter.setFileSystem(fs);\n    return fs;\n  }\n\n  private void enforceRootPath(HttpFSFileSystem.Operation op, String path) {\n    if (!path.equals(\"/\")) {\n      throw new UnsupportedOperationException(\n        MessageFormat.format(\"Operation [{0}], invalid path [{1}], must be '/'\",\n                             op, path));\n    }\n  }\n\n  /**\n   * Special binding for '/' as it is not handled by the wildcard binding.\n   *\n   * @param uriInfo uri info of the request.\n   * @param op the HttpFS operation of the request.\n   *\n   * @return the request response.\n   *\n   * @throws IOException thrown if an IO error occurred. Thrown exceptions are\n   * handled by {@link HttpFSExceptionProvider}.\n   * @throws FileSystemAccessException thrown if a FileSystemAccess releated\n   * error occurred. Thrown exceptions are handled by\n   * {@link HttpFSExceptionProvider}.","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java#L182-L218","documentation":"Some HttpFS operations are bound only at the filesystem root (notably HOMEDIR, INSTRUMENTATION, and the root-level bindings) and HttpFSServer.enforceRootPath() rejects any request where the path parameter is not exactly '/'. The message names the operation and the offending path so you can see which request was misrouted.","triggerScenarios":"GET /webhdfs/v1/user/alice?op=HOMEDIR (any path other than '/'); /webhdfs/v1/data?op=INSTRUMENTATION; a client library that always appends a path prefix, or a proxy that rewrites the path part of the URL before it reaches HttpFS.","commonSituations":"Hand-crafted curl calls where the user forgets these ops are root-only; client wrappers that route every op through a configurable base path; gateways (Knox and similar) stripping or prefixing path segments; scripts that template the path as something like /${user}.","solutions":["Re-issue the request against the root: GET /webhdfs/v1/?op=HOMEDIR&user.name=alice.","Audit any proxy/gateway between client and HttpFS for path rewriting; the path must arrive as exactly '/'.","If writing a client wrapper, special-case root-only operations to always send the '/' path."],"exampleFix":"# before\n$ curl 'http://host:14000/webhdfs/v1/user/alice?op=HOMEDIR&user.name=alice'\n\n# after\n$ curl 'http://host:14000/webhdfs/v1/?op=HOMEDIR&user.name=alice'","handlingStrategy":"validation","validationCode":"Set<String> ROOT_ONLY_OPS = Set.of(\"HOMEDIR\", \"INSTRUMENTATION\", \"GETTRASHROOT\", \"GETQUOTAUSAGE\");\nString path = \"/\";  // always send root for these ops\nif (ROOT_ONLY_OPS.contains(op) && !\"/\".equals(path)) {\n  throw new IllegalArgumentException(op + \" must target path '/'\");\n}","typeGuard":"static boolean isRootOnlyOp(String op) {\n  return Set.of(\"HOMEDIR\", \"INSTRUMENTATION\", \"GETTRASHROOT\", \"GETQUOTAUSAGE\").contains(op);\n}","tryCatchPattern":"try {\n  resp = get(url + \"/webhdfs/v1/\" + path + \"?op=\" + op);\n} catch (IOException e) {\n  if (e.getMessage().contains(\"must be '/'\")) { /* retry once against root */\n    resp = get(url + \"/webhdfs/v1/?op=\" + op);\n  } else throw e;\n}","preventionTips":["Special-case root-only ops in client wrappers to always send '/'.","Keep e2e REST smoke tests covering each op your tooling uses.","Beware proxies that prepend/strip path segments in front of HttpFS."],"tags":["httpfs","webhdfs","rest-api","request-path","validation"],"backgroundTag":"invalid-request-path","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}