apache/hadoop · error · NativeIOException

EBADF

EBADF

Error message

The handle is invalid.

What it means

On Windows, NativeIO.getFstat(FileDescriptor) maps Win32 error 6 (ERROR_INVALID_HANDLE) to NativeIOException("The handle is invalid.", Errno.EBADF). The FileDescriptor passed in is closed, stale, or not resolvable to a valid OS handle by the native layer.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/NativeIO.java:589

    /**
     * Returns the file stat for a file descriptor.
     *
     * @param fd file descriptor.
     * @return the file descriptor file stat.
     * @throws IOException thrown if there was an IO error while obtaining the file stat.
     */
    public static Stat getFstat(FileDescriptor fd) throws IOException {
      Stat stat = null;
      if (!Shell.WINDOWS) {
        stat = fstat(fd); 
        stat.owner = getName(IdCache.USER, stat.ownerId);
        stat.group = getName(IdCache.GROUP, stat.groupId);
      } else {
        try {
          stat = fstat(fd);
        } catch (NativeIOException nioe) {
          if (nioe.getErrorCode() == 6) {
            throw new NativeIOException("The handle is invalid.",
                Errno.EBADF);
          } else {
            LOG.warn(String.format("NativeIO.getFstat error (%d): %s",
                nioe.getErrorCode(), nioe.getMessage()));
            throw new NativeIOException("Unknown error", Errno.UNKNOWN);
          }
        }
      }
      return stat;
    }

    /**
     * Return the file stat for a file path.
     *
     * @param path  file path
     * @return  the file stat
     * @throws IOException  thrown if there is an IO error while obtaining the
     * file stat

View on GitHub (pinned to 2add963021)

Solutions

  1. Reorder so the fstat happens while the stream is still open — stat first, then close.
  2. Audit fd ownership: exactly one owner, no caching across close(), close in finally at the end of use.
  3. In tests use real temporary files (JUnit TemporaryFolder) instead of fabricated descriptors.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  Stat st = NativeIO.getFstat(fd);
} catch (NativeIOException e) {
  if (e.getErrno() == Errno.EBADF) {
    // fd closed/invalid: reopen the file or skip — a lifecycle bug, not transient
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling getFstat with a FileDescriptor captured from a stream that was already closed(); reusing a fd stored after its owner closed; a fd fabricated or mocked rather than obtained from a real open file.

Common situations: Close-then-stat ordering bugs (stat after finally-close); fd cached across operations and outliving its stream; tests constructing fake FileDescriptors.

Related errors


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