quarkusio/quarkus · error · IllegalArgumentException

Offset + count (${offset + count}) larger than file size (${

Error message

Offset + count (${offset + count}) larger than file size (${file.length()}): ${file}

What it means

FilePart validates that the requested range (offset + count) fits within the actual file size. Requesting more bytes than the file contains would produce a truncated/invalid transfer, so the constructor throws this IllegalArgumentException listing the computed range, file size, and file.

Source

Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/FilePart.java:44

     * Create a new partial {@link File} object.
     *
     * @param file The file to send
     * @param offset The starting byte of the file (must be >= 0)
     * @param count The number of bytes to send (must be >= 0 and offset+count <= file size)
     */
    public FilePart(File file, long offset, long count) {
        if (!file.exists())
            throw new IllegalArgumentException("File does not exist: " + file);
        if (!file.isFile())
            throw new IllegalArgumentException("File is not a regular file: " + file);
        if (!file.canRead())
            throw new IllegalArgumentException("File cannot be read: " + file);
        if (offset < 0)
            throw new IllegalArgumentException("Offset (" + offset + ") must be >= 0: " + file);
        if (count < 0)
            throw new IllegalArgumentException("Count (" + count + ") must be >= 0: " + file);
        if ((offset + count) > file.length())
            throw new IllegalArgumentException(
                    "Offset + count (" + (offset + count) + ") larger than file size (" + file.length() + "): " + file);
        this.file = file;
        this.offset = offset;
        this.count = count;
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Re-read file.length() immediately before constructing the FilePart instead of using a cached size.
  2. Clamp the range: count = Math.min(count, file.length() - offset).
  3. Use Files.size(Path) on a freshly opened/locked snapshot of the file if it changes concurrently.
  4. Log the actual file size and requested range to diagnose which is stale.

Example fix

// before
long size = cachedLength; // stale
new FilePart(file, offset, size);
// after
long size = file.length();
long count = Math.min(size - offset, requestedCount);
new FilePart(file, offset, count);
Defensive patterns

Strategy: validation

Validate before calling

long len = file.length();
if (offset + count > len) {
    count = Math.max(0, len - offset); // clamp to actual size
}
FilePart part = new FilePart(file, offset, count);

Type guard

static boolean rangeFits(File f, long offset, long count) {
    return f != null && offset >= 0 && count >= 0 && offset <= f.length() && offset + count <= f.length();
}

Try / catch

try {
    return new FilePart(file, offset, count);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Offset + count")) {
        log.warn("Range [{}..{}] exceeds size {} of {}, reclamping", offset, offset + count, file.length(), file);
        return new FilePart(file, offset, Math.max(0, file.length() - offset));
    }
    throw e;
}

Prevention

When it happens

Trigger: new FilePart(file, offset, count) where offset + count > file.length(), e.g. using a stale file-length captured before the file was rewritten to a smaller size.

Common situations: Caching file length from a previous version of the file that was later truncated or replaced; hardcoding counts instead of using file.length(); race where another process shrinks the file between length check and construction.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7db84b03567e87ce. Report an issue: GitHub.