{"record":{"id":"f97b09357cccf6c4","repo":"apache/hadoop","slug":"expected-http-status-was-307-received-0","errorCode":null,"errorMessage":"Expected HTTP status was [307], received [{0}]","messagePattern":"Expected HTTP status was \\[307\\], received \\[(.+?)\\]","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java","lineNumber":593,"sourceCode":"      if (conn.getResponseCode() == HTTP_TEMPORARY_REDIRECT) {\n        exceptionAlreadyHandled = true;\n        String location = conn.getHeaderField(\"Location\");\n        if (location != null) {\n          conn = getConnection(new URL(location), method);\n          conn.setRequestProperty(\"Content-Type\", UPLOAD_CONTENT_TYPE);\n          try {\n            OutputStream os = new BufferedOutputStream(conn.getOutputStream(), bufferSize);\n            return new HttpFSDataOutputStream(conn, os, expectedStatus, statistics);\n          } catch (IOException ex) {\n            HttpExceptionUtils.validateResponse(conn, expectedStatus);\n            throw ex;\n          }\n        } else {\n          HttpExceptionUtils.validateResponse(conn, HTTP_TEMPORARY_REDIRECT);\n          throw new IOException(\"Missing HTTP 'Location' header for [\" + conn.getURL() + \"]\");\n        }\n      } else {\n        throw new IOException(\n          MessageFormat.format(\"Expected HTTP status was [307], received [{0}]\",\n                               conn.getResponseCode()));\n      }\n    } catch (IOException ex) {\n      if (exceptionAlreadyHandled) {\n        throw ex;\n      } else {\n        HttpExceptionUtils.validateResponse(conn, HTTP_TEMPORARY_REDIRECT);\n        throw ex;\n      }\n    }\n  }\n\n\n  /**\n   * Opens an FSDataOutputStream at the indicated Path with write-progress\n   * reporting.\n   * <p>","sourceCodeStart":575,"sourceCodeEnd":611,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java#L575-L611","documentation":"HttpFSFileSystem.uploadData() implements the two-step WebHDFS write protocol: the first CREATE or APPEND request must be answered by the server with HTTP 307 Temporary Redirect whose Location header points at the URL that accepts the data. If the first response carries any other non-error status code (HttpExceptionUtils.validateResponse lets 2xx pass silently, so this raw IOException survives the outer catch), the client throws 'Expected HTTP status was [307], received [n]'. It means something answered the request directly instead of issuing the protocol-mandated redirect.","triggerScenarios":"Calling fs.create(path) or fs.append(path) on a webhdfs/swebhdfs FileSystem when the first response is 200/302/403-without-error-body etc.: a reverse proxy (nginx/Apache) or auth filter in front of HttpFS that serves the request itself, a rewrite rule absorbing the redirect, or an HttpFS/WebHDFS server version that no longer uses the redirect handshake for that operation.","commonSituations":"SSL-offloading load balancer that converts the 307 into a 200; an SSO gate returning an HTML page with status 200; pointing the webhdfs:// URI at a plain Tomcat webapp instead of the HttpFS /webhdfs/v1 endpoint; client jar and server Hadoop major-version mismatch (protocol drift between 2.x and 3.x).","solutions":["Reproduce the first request with curl -i 'http://host:14000/webhdfs/v1/<path>?op=CREATE&...' and check the actual status, Location header, and body to identify what is answering","If a proxy/load-balancer fronts HttpFS, configure it to pass the 307 and its Location header through untouched (proxy_pass, no redirect rewrite, preserve host)","Confirm the URL hits the HttpFS WebHDFS endpoint (/webhdfs/v1) on the HttpFS port (default 14000) and that the server is actually HttpFS/WebHDFS, not another webapp","Align the hadoop-hdfs-httpfs client jar version with the server version so both sides speak the same redirect protocol","If the status is 4xx/5xx, read the error payload instead: HttpExceptionUtils.validateResponse in the catch block usually surfaces the real server-side cause first"],"exampleFix":"// before: nginx absorbed the redirect\n// location /webhdfs { proxy_pass http://httpfs; proxy_redirect http:// https://; }\n// after: pass the 307 through untouched\n// location /webhdfs {\n//   proxy_pass http://httpfs:14000;\n//   proxy_set_header Host $host;\n// }  # then: curl -i '.../webhdfs/v1/f?op=CREATE' must show: HTTP/1.1 307 Temporary Redirect + Location:","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  out = fs.create(path, true);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Expected HTTP status was [307]\")) {\n    // first CREATE/APPEND response was non-error but not 307:\n    // something in front of HttpFS answered instead of redirecting\n    LOG.warn(\"CREATE not redirected (307) by {} - check proxy/server\", uri);\n  }\n  throw e;\n}","preventionTips":["Smoke-test the write path at deploy time: curl -i the first CREATE request and assert HTTP 307 plus a Location header","Keep fronting proxies from rewriting redirects (no proxy_redirect, preserve Location)","Pin client hadoop-hdfs-httpfs and HttpFS server to the same release line"],"tags":["webhdfs","httpfs","http-307-redirect","create-append","reverse-proxy"],"backgroundTag":"unexpected-http-status","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}