apache/hadoop · error · IOException
Byte-per-checksum not matched: bpc={} but bytesPerCRC={}
Error message
Byte-per-checksum not matched: bpc={} but bytesPerCRC={} What it means
While computing an MD5MD5CRC file checksum, the client reads each block's checksum header and requires bytesPerCRC (io.bytes.per.checksum) to be identical across all blocks — the MD5-of-MD5s combination is only defined for uniform chunking. If a later block reports a different bpc than the first block and the mode is not COMPOSITE_CRC, it throws this IOException. COMPOSITE_CRC is specifically designed to tolerate varying bytesPerCRC, which is why the code just logs a warning and continues in that mode.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/FileChecksumHelper.java:385
void extractChecksumProperties(
OpBlockChecksumResponseProto checksumData,
LocatedBlock locatedBlock,
DatanodeInfo datanode,
int blockIdx)
throws IOException {
//read byte-per-checksum
final int bpc = checksumData.getBytesPerCrc();
if (blockIdx == 0) { //first block
setBytesPerCRC(bpc);
} else if (bpc != getBytesPerCRC()) {
if (getBlockChecksumType() == BlockChecksumType.COMPOSITE_CRC) {
LOG.warn(
"Current bytesPerCRC={} doesn't match next bpc={}, but "
+ "continuing anyway because we're using COMPOSITE_CRC. "
+ "If trying to preserve CHECKSUMTYPE, only the current "
+ "bytesPerCRC will be preserved.", getBytesPerCRC(), bpc);
} else {
throw new IOException("Byte-per-checksum not matched: bpc=" + bpc
+ " but bytesPerCRC=" + getBytesPerCRC());
}
}
//read crc-per-block
final long cpb = checksumData.getCrcPerBlock();
if (getLocatedBlocks().size() > 1 && blockIdx == 0) {
setCrcPerBlock(cpb);
}
// read crc-type
final DataChecksum.Type ct;
if (checksumData.hasCrcType()) {
ct = PBHelperClient.convert(checksumData.getCrcType());
} else {
LOG.debug("Retrieving checksum from an earlier-version DataNode: " +
"inferring checksum by reading first byte");
ct = getClient().inferChecksumTypeByReading(locatedBlock, datanode);View on GitHub (pinned to 2add963021)
Solutions
- Set dfs.checksum.combine.mode=COMPOSITE_CRC on the client (and both sides for distcp) — it supports differing bytesPerCRC by design
- For distcp, drop checksum verification (-skip-checksum-difference) or use COMPOSITE_CRC on both clusters
- Rewrite the file (hdfs dfs -get/-put, or distcp without -p checksum) to normalize all blocks to current checksum settings
- Prevent recurrence: keep io.bytes.per.checksum stable for the lifetime of files that will be appended to
Example fix
<!-- before --> <property> <name>dfs.checksum.combine.mode</name> <value>MD5MD5CRC</value> </property> <!-- after: tolerate per-block bytesPerCRC differences --> <property> <name>dfs.checksum.combine.mode</name> <value>COMPOSITE_CRC</value> </property>
Defensive patterns
Strategy: fallback
Validate before calling
// Before a checksum job over legacy data, check per-block checksum settings
// via a probe read: compute checksum of a small range and on failure switch mode.
// Simplest up-front guard: choose COMPOSITE_CRC when files may be heterogeneous.
conf.set("dfs.checksum.combine.mode", "COMPOSITE_CRC"); Try / catch
try {
return fs.getFileChecksum(path); // MD5MD5CRC default
} catch (IOException e) {
if (e.getMessage().contains("Byte-per-checksum not matched")) {
conf.set("dfs.checksum.combine.mode", "COMPOSITE_CRC");
return fs.getFileChecksum(path); // tolerant combine mode
}
throw e;
} Prevention
- Standardize io.bytes.per.checksum cluster-wide and never append to files written under a different value without expecting checksum issues
- For distcp -crc over historical data, set dfs.checksum.combine.mode=COMPOSITE_CRC on both ends
- Expect legacy files to have 512-byte checksums; new files with custom values mixed via append will not verify under MD5MD5CRC
When it happens
Trigger: getFileChecksum()/DistCp -crc over a file whose blocks were written with different io.bytes.per.checksum values — e.g., appended after the cluster/client checksum config changed, files created pre- and post-config-change, or concatenated files (hdfs dfs -concat) with heterogeneous chunk sizes; the first block fixes bytesPerCRC and a subsequent block disagrees.
Common situations: Appends to old files after io.bytes.per.checksum was changed; distcp between clusters with different checksum settings using -crc/-p checksum; verifying checksums of archived data written under legacy 512-byte settings vs newer custom values.
Related errors
- Invalid checksum type in dfs.checksum.type: {}
- Invalid checksum type: userOpt={}, default={}, effective=nul
- Invalid values: dfs.bytes-per-checksum (={}) must divide cel
- Unknown ChecksumCombineMode: {}
- DataChecksum.Type.MIXED is not supported for COMPOSITE_CRC
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/5660873d35422808.
Report an issue: GitHub.