LSPosed/LSPosed · error · IllegalArgumentException

Offset ${offset} is out of range for ${filename}

Error message

Offset ${offset} is out of range for ${filename}

What it means

DirectAccessService.readFile(filename, offset, length, previousSize, previousTime) throws IllegalArgumentException when a positive offset is greater than or equal to the current file size. The range check at line 93 exists because the subsequent FileInputStream.skip(offset) would have nothing left to read, so the API rejects the call instead of returning empty data.

Source

Thrown at core/src/main/java/de/robv/android/xposed/services/DirectAccessService.java:94

        // Check range
        if (offset > 0 && offset >= size) {
            throw new IllegalArgumentException("Offset " + offset + " is out of range for " + filename);
        } else if (offset < 0) {
            offset = 0;
        }

View on GitHub (pinned to df74d83eb0)

Solutions

  1. Re-stat the file (statFile) before reading and clamp offset to Math.min(offset, size - 1) or re-read from 0
  2. If the file was rotated/truncated, reset your cached previousSize/previousTime and read the whole file
  3. Handle offset <= 0 if you actually want the whole file — that takes the readFile shortcut with no range check

Example fix

// before
FileResult r = service.readFile(path, cachedOffset, len, prevSize, prevTime);

// after
FileResult st = service.statFile(path);
if (cachedOffset >= st.size) {
    cachedOffset = 0; // file shrank or rotated, restart
}
FileResult r = service.readFile(path, (int) cachedOffset, len, st.size, st.mtime);
Defensive patterns

Strategy: validation

Validate before calling

FileResult st = service.statFile(filename);
if (offset > 0 && offset >= st.size) {
    offset = 0; // file shrank/rotated — restart from beginning
}

Try / catch

try {
    return service.readFile(filename, offset, length, prevSize, prevTime);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Offset")) {
        return service.readFile(filename); // fall back to full read
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling readFile(path, offset, length, prevSize, prevTime) with offset >= file.length(), typically after the file shrank or was truncated between a previous stat/read and this call (previousSize/previousTime mismatch forces the full read path).

Common situations: Polling a log or config file that gets rotated/truncated (e.g. logcat-style rotation); caching (size, mtime) from a previous read and re-reading with an old offset after the file was recreated smaller.

Related errors


AI-assisted analysis of LSPosed/LSPosed@df74d83eb0 (2026-08-14). Data as JSON: /api/errors/19d4dfb9574e8299. Report an issue: GitHub.