{"record":{"id":"f7ce4de011962176","repo":"apache/hadoop","slug":"cannot-truncate-to-a-negative-file-size-f7ce4d","errorCode":null,"errorMessage":"Cannot truncate to a negative file size: {}.","messagePattern":"Cannot truncate to a negative file size: (.+?)\\.","errorType":"exception","errorClass":"HadoopIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DFSClient.java","lineNumber":1681,"sourceCode":"          QuotaByStorageTypeExceededException.class,\n          FileAlreadyExistsException.class,\n          FileNotFoundException.class,\n          ParentNotDirectoryException.class,\n          SafeModeException.class,\n          NSQuotaExceededException.class,\n          UnresolvedPathException.class,\n          SnapshotAccessControlException.class);\n    }\n  }\n\n  /**\n   * Truncate a file to an indicated size\n   * See {@link ClientProtocol#truncate}.\n   */\n  public boolean truncate(String src, long newLength) throws IOException {\n    checkOpen();\n    if (newLength < 0) {\n      throw new HadoopIllegalArgumentException(\n          \"Cannot truncate to a negative file size: \" + newLength + \".\");\n    }\n    try (TraceScope ignored = newPathTraceScope(\"truncate\", src)) {\n      return namenode.truncate(src, newLength, clientName);\n    } catch (RemoteException re) {\n      throw re.unwrapRemoteException(AccessControlException.class,\n          UnresolvedPathException.class);\n    }\n  }\n\n  /**\n   * Delete file or directory.\n   * See {@link ClientProtocol#delete(String, boolean)}.\n   */\n  @Deprecated\n  public boolean delete(String src) throws IOException {\n    checkOpen();\n    return delete(src, true);","sourceCodeStart":1663,"sourceCodeEnd":1699,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DFSClient.java#L1663-L1699","documentation":"DFSClient.truncate() validates the target size client-side before any RPC: newLength < 0 is rejected with HadoopIllegalArgumentException. Negative sizes can only come from caller arithmetic (the protocol has no negative lengths), so this is a guard against underflow or unvalidated user input rather than a server condition.","triggerScenarios":"Computing newLength = currentLen - bytesToDrop where bytesToDrop > currentLen (reads a stale length, or a concurrent truncate shrank the file first); passing a user-supplied size string like '-1' straight through; compensating logic subtracting more than the file holds.","commonSituations":"Interactive tools accepting user sizes without validation; retry/rollback code truncating back to an old offset computed from a different file version; unit tests probing boundary values.","solutions":["Clamp before calling: newLength = Math.max(0L, Math.min(newLength, fileLen)) with fileLen freshly read.","Validate sizes at your API/CLI boundary and reject negatives there with a clear message.","Fix the subtraction site: re-read the file length immediately before computing the delta."],"exampleFix":"// before\nlong target = fileLen - bytesToDrop; // negative when bytesToDrop > fileLen\nboolean finished = dfs.truncate(path, target);\n\n// after\nlong target = Math.max(0L, fileLen - bytesToDrop);\nboolean finished = dfs.truncate(path, target);","handlingStrategy":"validation","validationCode":"long fileLen = fs.getFileStatus(path).getLen();\nlong target = Math.max(0L, Math.min(newLength, fileLen));\nif (newLength < 0) { throw new IllegalArgumentException(\"negative truncate size: \" + newLength); }","typeGuard":null,"tryCatchPattern":"catch (HadoopIllegalArgumentException e) {\n  // surface the invalid newLength to the caller/config owner with the computed value\n}","preventionTips":["Clamp truncate targets to [0, fileLen] with a freshly read length.","Reject negative sizes at parse time in CLIs and APIs.","Treat a negative computed target as a logic bug (stale length), not as user input."],"tags":["hdfs","truncate","argument-validation","arithmetic-underflow"],"backgroundTag":"invalid-argument","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}