apache/hadoop · error · IOException

Expected HTTP status was [307], received [{0}]

Error message

Expected HTTP status was [307], received [{0}]

What it means

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.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/client/HttpFSFileSystem.java:593

      if (conn.getResponseCode() == HTTP_TEMPORARY_REDIRECT) {
        exceptionAlreadyHandled = true;
        String location = conn.getHeaderField("Location");
        if (location != null) {
          conn = getConnection(new URL(location), method);
          conn.setRequestProperty("Content-Type", UPLOAD_CONTENT_TYPE);
          try {
            OutputStream os = new BufferedOutputStream(conn.getOutputStream(), bufferSize);
            return new HttpFSDataOutputStream(conn, os, expectedStatus, statistics);
          } catch (IOException ex) {
            HttpExceptionUtils.validateResponse(conn, expectedStatus);
            throw ex;
          }
        } else {
          HttpExceptionUtils.validateResponse(conn, HTTP_TEMPORARY_REDIRECT);
          throw new IOException("Missing HTTP 'Location' header for [" + conn.getURL() + "]");
        }
      } else {
        throw new IOException(
          MessageFormat.format("Expected HTTP status was [307], received [{0}]",
                               conn.getResponseCode()));
      }
    } catch (IOException ex) {
      if (exceptionAlreadyHandled) {
        throw ex;
      } else {
        HttpExceptionUtils.validateResponse(conn, HTTP_TEMPORARY_REDIRECT);
        throw ex;
      }
    }
  }


  /**
   * Opens an FSDataOutputStream at the indicated Path with write-progress
   * reporting.
   * <p>

View on GitHub (pinned to 2add963021)

Solutions

  1. 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
  2. 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)
  3. 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
  4. Align the hadoop-hdfs-httpfs client jar version with the server version so both sides speak the same redirect protocol
  5. 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

Example fix

// before: nginx absorbed the redirect
// location /webhdfs { proxy_pass http://httpfs; proxy_redirect http:// https://; }
// after: pass the 307 through untouched
// location /webhdfs {
//   proxy_pass http://httpfs:14000;
//   proxy_set_header Host $host;
// }  # then: curl -i '.../webhdfs/v1/f?op=CREATE' must show: HTTP/1.1 307 Temporary Redirect + Location:
Defensive patterns

Strategy: try-catch

Try / catch

try {
  out = fs.create(path, true);
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().contains("Expected HTTP status was [307]")) {
    // first CREATE/APPEND response was non-error but not 307:
    // something in front of HttpFS answered instead of redirecting
    LOG.warn("CREATE not redirected (307) by {} - check proxy/server", uri);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/f97b09357cccf6c4. Report an issue: GitHub.