apache/hadoop · error · HadoopIllegalArgumentException
Cannot truncate to a negative file size: {}.
Error message
Cannot truncate to a negative file size: {}. What it means
FSNamesystem.truncate validates newLength before taking locks or logging edits: a negative target size is meaningless for a file and is rejected immediately with HadoopIllegalArgumentException.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java:2421
* Truncation at block boundary is atomic, otherwise it requires
* block recovery to truncate the last block of the file.
*
* @return true if client does not need to wait for block recovery,
* false if client needs to wait for block recovery.
*/
boolean truncate(String src, long newLength, String clientName,
String clientMachine, long mtime) throws IOException,
UnresolvedLinkException {
final String operationName = "truncate";
requireEffectiveLayoutVersionForFeature(Feature.TRUNCATE);
FSDirTruncateOp.TruncateResult r = null;
FileStatus status;
try {
NameNode.stateChangeLog.info(
"DIR* NameSystem.truncate: src={} newLength={}", src, newLength);
if (newLength < 0) {
throw new HadoopIllegalArgumentException(
"Cannot truncate to a negative file size: " + newLength + ".");
}
checkOperation(OperationCategory.WRITE);
final FSPermissionChecker pc = getPermissionChecker();
FSPermissionChecker.setOperationType(operationName);
writeLock(RwLockMode.GLOBAL);
BlocksMapUpdateInfo toRemoveBlocks = new BlocksMapUpdateInfo();
try {
checkOperation(OperationCategory.WRITE);
checkNameNodeSafeMode("Cannot truncate for " + src);
r = FSDirTruncateOp.truncate(this, src, newLength, clientName,
clientMachine, mtime, toRemoveBlocks, pc);
} finally {
status = r != null ? r.getFileStatus() : null;
writeUnlock(RwLockMode.GLOBAL, operationName,
getLockReportInfoSupplier(src, null, status));
}
getEditLog().logSync();View on GitHub (pinned to 2add963021)
Solutions
- Clamp before calling: newLength = Math.max(0, Math.min(newLength, fileLen))
- Validate numeric input at the boundary and reject negative sizes with your own error message
- Treat -1/NaN from stat-like calls as errors, never as lengths
Example fix
// before
fs.truncate(path, requestedLen);
// after
long fileLen = fs.getFileStatus(path).getLen();
long target = Math.max(0L, Math.min(requestedLen, fileLen));
if (target != requestedLen) LOG.warn("clamped truncate target from {} to {}", requestedLen, target);
fs.truncate(path, target); Defensive patterns
Strategy: validation
Validate before calling
if (newLength < 0) throw new IllegalArgumentException("newLength must be >= 0: " + newLength);
long fileLen = fs.getFileStatus(path).getLen();
if (newLength > fileLen) throw new IllegalArgumentException("newLength " + newLength + " > file size " + fileLen); Prevention
- Never forward raw user input as byte lengths
- Treat -1 from stat-style calls as an error, never a size
When it happens
Trigger: ClientProtocol.truncate / DistributedFileSystem.truncate(path, newLength) invoked with newLength < 0 — usually unchecked arithmetic such as newLen = currentLen - delta where delta > currentLen, a -1 sentinel from a failed stat call, or raw user input forwarded unvalidated.
Common situations: Apps computing truncation offsets from sizes fetched from another system whose API returned -1 on error; CLI tools forwarding raw numeric arguments; unit tests with edge-case sizes hitting a real cluster.
Related errors
- Cannot truncate to a larger file size. Current size: <oldLen
- Cannot truncate to a negative file size: {}.
- Not implemented by the {} FileSystem implementation
- Illegal option {}
- Not enough arguments: expected {} but got {}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/878fef3d7f4550b0.
Report an issue: GitHub.