apache/hadoop · error · IOException
Block InputStream has no FileChannel.
Error message
Block InputStream has no FileChannel.
What it means
Thrown by MemoryMappableBlockLoader.load() (MemoryMappableBlockLoader.java:77), the DRAM (mmap+mlock) loader for HDFS centralized caching, when blockIn.getChannel() returns null. As with the other loaders this is a defensive check - FileInputStream.getChannel() on a stock JDK never returns null - so the branch is effectively theoretical; the realistic failure modes of this loader are mmap/mlock failures (ulimits), which throw different errors.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/MemoryMappableBlockLoader.java:77
* start. The caller must close this.
* @param metaIn The meta file input stream. Should be positioned at
* the start. The caller must close this.
* @param blockFileName The block file name, for logging purposes.
* @param key The extended block ID.
*
* @throws IOException If mapping block to memory fails or checksum fails.
* @return The Mappable block.
*/
@Override
MappableBlock load(long length, FileInputStream blockIn,
FileInputStream metaIn, String blockFileName, ExtendedBlockId key)
throws IOException {
MemoryMappedBlock mappableBlock = null;
MappedByteBuffer mmap = null;
try (FileChannel blockChannel = blockIn.getChannel()) {
if (blockChannel == null) {
throw new IOException("Block InputStream has no FileChannel.");
}
mmap = blockChannel.map(FileChannel.MapMode.READ_ONLY, 0, length);
NativeIO.POSIX.getCacheManipulator().mlock(blockFileName, mmap, length);
verifyChecksum(length, metaIn, blockChannel, blockFileName);
mappableBlock = new MemoryMappedBlock(mmap, length);
} finally {
if (mappableBlock == null) {
if (mmap != null) {
NativeIO.POSIX.munmap(mmap); // unmapping also unlocks
}
}
}
return mappableBlock;
}
@Override
public long getCacheUsed() {
return memCacheStats.getCacheUsed();View on GitHub (pinned to 2add963021)
Solutions
- Reproduce on a stock supported JDK; remove JVM agents/instrumentation and retest
- If it persists, capture the FileInputStream concrete class in the exception (getClass()) via a debug patch and file a Hadoop JIRA
- FsDatasetCache already marks the caching attempt failed and frees the reservation - no manual cleanup beyond retrying the directive is needed
Defensive patterns
Strategy: try-catch
Try / catch
try {
mappableBlock = new MemoryMappableBlockLoader(...).load(
length, blockIn, metaIn, blockFileName, key);
} catch (IOException e) {
// load() already munmaps on failure in its finally; just report and let the cache retry
LOG.warn("DRAM caching failed for {}: {}", key, e);
} Prevention
- Use a stock JDK; the null-channel guard is unreachable in normal operation
- For the realistic mlock failures instead: raise ulimits (memlock) and set dfs.datanode.max.locked.memory
When it happens
Trigger: A cache directive on a cluster with dfs.datanode.max.locked.memory configured, where blockIn is somehow not backed by a real file channel (custom/instrumented JDK, exotic filesystem returning unusable channels).
Common situations: Practically does not occur; if reported, look at JVM-level tampering (agents, patched JDK) rather than HDFS configuration.
Related errors
- Block InputStream meta file has no FileChannel.
- Block InputStream has no FileChannel.
- Cannot get FileChannel from Block InputStream meta file.
- Block InputStream has no FileChannel.
- Cannot start datanode because the configured max locked memo
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/3a833743115187c7.
Report an issue: GitHub.