apache/hadoop · error · IOException

No filename header provided by server

Error message

No filename header provided by server

What it means

Util.receiveFile writes the downloaded image into each localPath; when a localPath is an existing directory, the target filename must come from the server's fsimage name header (ImageServlet.HADOOP_IMAGE_EDITS_HEADER). If that header is null the file cannot be placed, so the download fails fast.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Util.java:215

   * the specified destination storage location.
   */
  public static MD5Hash receiveFile(String url, List<File> localPaths,
      Storage dstStorage, boolean getChecksum, long advertisedSize,
      MD5Hash advertisedDigest, String fsImageName, InputStream stream,
      DataTransferThrottler throttler) throws
      IOException {
    long startTime = Time.monotonicNow();
    Map<FileOutputStream, File> streamPathMap = new HashMap<>();
    StringBuilder xferStats = new StringBuilder();
    double xferCombined = 0;
    if (localPaths != null) {
      // If the local paths refer to directories, use the server-provided header
      // as the filename within that directory
      List<File> newLocalPaths = new ArrayList<>();
      for (File localPath : localPaths) {
        if (localPath.isDirectory()) {
          if (fsImageName == null) {
            throw new IOException("No filename header provided by server");
          }
          newLocalPaths.add(new File(localPath, fsImageName));
        } else {
          newLocalPaths.add(localPath);
        }
      }
      localPaths = newLocalPaths;
    }


    long received = 0;
    MessageDigest digester = null;
    if (getChecksum) {
      digester = MD5Hash.getDigester();
      stream = new DigestInputStream(stream, digester);
    }
    boolean finishedReceiving = false;
    int num = 1;

View on GitHub (pinned to 2add963021)

Solutions

  1. Pass explicit file paths in localPaths instead of directories, so the header is not needed
  2. Ensure the endpoint is the stock GetImageServlet, which always sets the header
  3. If a proxy is in the path, allow the custom HADOOP_IMAGE_EDITS_HEADER through

Example fix

// before
List<File> localPaths = Collections.singletonList(new File("/data/nn/current")); // directory
Util.doGetUrl(url, localPaths, storage, true, 0, null);

// after
List<File> localPaths = Collections.singletonList(
    new File("/data/nn/current/fsimage_0000000000000000123")); // explicit file
Util.doGetUrl(url, localPaths, storage, true, 0, null);
Defensive patterns

Strategy: validation

Validate before calling

// Avoid needing the server-side filename header at all
for (File p : localPaths) {
  if (p.isDirectory()) {
    throw new IllegalArgumentException(
        "Pass an explicit file path, not a directory: " + p
            + " (server filename header may be absent)");
  }
}

Try / catch

try {
  Util.doGetUrl(url, localPaths, storage, false, timeoutMs, throttler);
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().contains("No filename header")) {
    // retry with explicit file targets instead of directories
  }
  throw e;
}

Prevention

When it happens

Trigger: Invoking Util.doGetUrl/receiveFile with localPaths that are directories while the server response omits the image-edits name header — e.g. a test or custom servlet in front of GetImageServlet that forwards the body but not the custom header.

Common situations: Custom tooling or tests that call these internals directly with a storage directory instead of a file path; a proxy stripping non-standard headers (HADOOP_IMAGE_EDITS_HEADER is custom, proxies may drop it).

Related errors


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