apache/hadoop · error · IOException

Block InputStream has no FileChannel.

Error message

Block InputStream has no FileChannel.

What it means

Thrown by PmemMappableBlockLoader.load() (PmemMappableBlockLoader.java:93) - the pure-Java pmem cache loader that copies the block file into the pmem volume via RandomAccessFile/transferTo - when blockIn.getChannel() returns null. As with the other loaders, FileInputStream.getChannel() on a stock JDK never returns null, so this is a defensive guard that normal workloads cannot reach; realistic failures on this path are pmem volume misconfiguration or I/O errors during the copy.

Source

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

   * @param key            The extended block ID.
   *
   * @throws IOException   If mapping block fails or checksum fails.
   *
   * @return               The Mappable block.
   */
  @Override
  MappableBlock load(long length, FileInputStream blockIn,
      FileInputStream metaIn, String blockFileName, ExtendedBlockId key)
      throws IOException {
    PmemMappedBlock mappableBlock = null;
    String cachePath = null;

    FileChannel blockChannel = null;
    RandomAccessFile cacheFile = null;
    try {
      blockChannel = blockIn.getChannel();
      if (blockChannel == null) {
        throw new IOException("Block InputStream has no FileChannel.");
      }
      cachePath = pmemVolumeManager.getCachePath(key);
      cacheFile = new RandomAccessFile(cachePath, "rw");
      blockChannel.transferTo(0, length, cacheFile.getChannel());

      // Verify checksum for the cached data instead of block file.
      // The file channel should be repositioned.
      cacheFile.getChannel().position(0);
      verifyChecksum(length, metaIn, cacheFile.getChannel(), blockFileName);

      mappableBlock = new PmemMappedBlock(length, key);
      LOG.info("Successfully cached one replica:{} into persistent memory"
          + ", [cached path={}, length={}]", key, cachePath, length);
    } finally {
      IOUtils.closeStream(blockChannel);
      IOUtils.closeStream(cacheFile);
      if (mappableBlock == null) {
        LOG.debug("Delete {} due to unsuccessful mapping.", cachePath);

View on GitHub (pinned to 2add963021)

Solutions

  1. Retest on a stock supported JDK with agents removed
  2. If reproducible, include the stream's concrete class in the exception via a debug patch and file a JIRA
  3. The single caching attempt fails cleanly and is retried by FsDatasetCache later; no manual uncache is needed
Defensive patterns

Strategy: try-catch

Try / catch

try {
  MappableBlock blk = pmemLoader.load(
      length, blockIn, metaIn, blockFileName, key);
} catch (IOException e) {
  // loader's finally closes the partial cache file; report and let the directive retry
  LOG.warn("pmem (java) caching failed for {}: {}", key, e);
}

Prevention

When it happens

Trigger: Only a non-standard JVM/instrumented stream could trip it; HDFS always passes a FileInputStream opened on the block file.

Common situations: Does not occur in practice; if reported, look at JDK-level tampering rather than dfs.datanode.pmem.cache.dirs or cache directives.

Related errors


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