apache/hadoop · error · IOException

Block InputStream has no FileChannel.

Error message

Block InputStream has no FileChannel.

What it means

Thrown by NativePmemMappableBlockLoader.load() (NativePmemMappableBlockLoader.java:87), the native libpmem loader for centralized caching on persistent memory, when blockIn.getChannel() returns null. This is the same defensive guard as the other loaders: FileInputStream.getChannel() on a stock JDK never returns null, so in practice this IOException is unreachable; realistic pmem caching failures surface later at Pmem.mapBlock instead.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/NativePmemMappableBlockLoader.java:87

   * @param key            The extended block ID.
   *
   * @throws IOException   If mapping block to persistent memory fails or
   *                       checksum fails.
   *
   * @return               The Mappable block.
   */
  @Override
  public MappableBlock load(long length, FileInputStream blockIn,
      FileInputStream metaIn, String blockFileName,
      ExtendedBlockId key)
      throws IOException {
    NativePmemMappedBlock mappableBlock = null;
    POSIX.PmemMappedRegion region = null;
    String filePath = null;

    try (FileChannel blockChannel = blockIn.getChannel()) {
      if (blockChannel == null) {
        throw new IOException("Block InputStream has no FileChannel.");
      }

      assert NativeIO.isAvailable();
      filePath = PmemVolumeManager.getInstance().getCachePath(key);
      region = POSIX.Pmem.mapBlock(filePath, length, false);
      if (region == null) {
        throw new IOException("Failed to map the block " + blockFileName +
            " to persistent storage.");
      }
      verifyChecksumAndMapBlock(region, length, metaIn, blockChannel,
          blockFileName);
      mappableBlock = new NativePmemMappedBlock(region.getAddress(),
          region.getLength(), key);
      LOG.info("Successfully cached one replica:{} into persistent memory"
              + ", [cached path={}, address={}, length={}]", key, filePath,
          region.getAddress(), length);
    } finally {
      if (mappableBlock == null) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Retest on a stock supported JDK without agents; the branch is defensive against impossible states
  2. If reproducible, capture the stream class in the message via a debug patch and file a JIRA
  3. The failure simply fails that one caching attempt; the cache directive retries automatically afterward
Defensive patterns

Strategy: try-catch

Try / catch

try {
  MappableBlock blk = nativePmemLoader.load(
      length, blockIn, metaIn, blockFileName, key);
} catch (IOException e) {
  // the finally block already unmaps any partial region; report and let the directive retry
  LOG.warn("Native pmem caching failed for {}: {}", key, e);
}

Prevention

When it happens

Trigger: Caching to pmem (dfs.datanode.pmem.cache.dirs set, native loader selected) on a JVM where getChannel() misbehaves - custom JDK builds or instrumentation. Standard Hadoop workloads cannot produce it.

Common situations: Essentially never; treat any occurrence as a JVM anomaly, not a HDFS/pmem configuration problem.

Related errors


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