{"record":{"id":"ea49817c5f22b50a","repo":"apache/druid","slug":"invalid-arguments-for-reading-s-from-d-reads","errorCode":null,"errorMessage":"Invalid arguments for reading %s. from = %d, readSize = %d, fileSize = %d","messagePattern":"Invalid arguments for reading (.+?)\\. from = (.+?), readSize = (.+?), fileSize = (.+?)","errorType":"validation","errorClass":"org.apache.druid.java.util.common.IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/storage/local/LocalFileStorageConnector.java","lineNumber":78,"sourceCode":"  {\n    return fileWithBasePath(path).exists();\n  }\n\n  @Override\n  public InputStream read(String path) throws IOException\n  {\n    return Files.newInputStream(fileWithBasePath(path).toPath());\n  }\n\n  @Override\n  public InputStream readRange(String path, long from, long size) throws IOException\n  {\n    if (!pathExists(path)) {\n      throw new FileNotFoundException(\"Unable to find file \" + fileWithBasePath(path).toPath() + \" for reading\");\n    }\n    long length = fileWithBasePath(path).length();\n    if (from < 0 || size < 0 || (from + size) > length) {\n      throw new IAE(\n          \"Invalid arguments for reading %s. from = %d, readSize = %d, fileSize = %d\",\n          fileWithBasePath(path).toPath(),\n          from,\n          size,\n          length\n      );\n    }\n    FileChannel fileChannel = FileChannel.open(fileWithBasePath(path).toPath(), StandardOpenOption.READ);\n    return new BoundedInputStream(Channels.newInputStream(fileChannel.position(from)), size);\n  }\n\n  /**\n   * Writes the file present with the materialized location as basePath + path.\n   * In case the parent directory does not exist, we create the parent dir recursively.\n   * Closing of the stream is the responsibility of the caller.\n   *\n   * @param path path to write contents to.\n   * @return OutputStream which can be used by callers to write contents.","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/storage/local/LocalFileStorageConnector.java#L60-L96","documentation":"LocalFileStorageConnector.readRange validates from >= 0, size >= 0, and from + size <= file length, throwing IAE with the resolved path, from, size, and actual file size when the requested window is invalid. It prevents out-of-bounds range reads on local files.","triggerScenarios":"readRange with negative from or size, or from+size exceeding the file length: using content-length from a HEAD on a different file version, off-by-one (fileLength instead of fileLength-1), unbounded size sentinel (-1) passed through.","commonSituations":"HTTP Range header parsing producing wrong offsets; file truncated/changed between stat and read; client passing -1 as size for 'to end' which this API does not support.","solutions":["Fetch the current file length via the connector and clamp: size = min(size, length - from), rejecting negatives.","Replace any 'read to end' sentinel (-1) with length - from before calling.","Re-stat the file and retry if it changed concurrently between length check and read.","Unit-test range math including edge cases from=length, size=0, and length=0 files."],"exampleFix":"// before\nconnector.readRange(path, from, -1); // invalid\n// after\nlong length = new File(basePath, path).length();\nlong readSize = (size < 0) ? length - from : Math.min(size, length - from);\nif (from < 0 || readSize < 0) {\n  throw new IAE(\"bad range: from=%d size=%d fileLen=%d\", from, size, length);\n}\nconnector.readRange(path, from, readSize);","handlingStrategy":"validation","validationCode":"long len = new File(basePath, path).length();\nif (from < 0 || size < 0 || from + size > len) throw new IllegalArgumentException(\"bad range \" + from + \"+\" + size + \">\" + len);","typeGuard":null,"tryCatchPattern":"try { in = connector.readRange(path, from, size); } catch (IllegalArgumentException e) { log.warn(e, \"invalid range for %s\", path); in = connector.readRange(path, 0, new File(basePath, path).length()); }","preventionTips":["Clamp size to length - from before calling.","Never pass -1 as size; compute length - from instead.","Re-stat file length right before ranged reads.","Test edge cases: empty files, from == length, size == 0."],"tags":["local-storage","range-check","arguments"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}