QL-Win/QuickLook · error · ArgumentException
Offset is before the current position in the stream.
Error message
Offset is before the current position in the stream.
What it means
Thrown by the Stream.GetBytes extension used by the PE parser: it computes bytesToSkip = index - stream.Position and requires this to be >= 0. A negative value means the requested `index` is behind the stream's current cursor, and because the method only supports forward skipping (it reads-and-discards), it throws ArgumentException rather than seeking.
Source
Thrown at QuickLook.Plugin/QuickLook.Plugin.PEViewer/PEImageParser/ImageSection.cs:84
/// </returns>
public static byte[] GetBytes(this byte[] array, int index, int count)
{
byte[] result = new byte[count];
Buffer.BlockCopy(array, index, result, 0, count);
return result;
}
public static byte[] GetBytes(this Stream stream, long index, int count)
{
byte[] buffer = new byte[count];
// Ensure the stream is at the correct position
long currentPosition = stream.Position;
long bytesToSkip = index - currentPosition;
if (bytesToSkip < 0)
{
throw new ArgumentException("Offset is before the current position in the stream.");
}
// Skip bytes until reaching the target offset
while (bytesToSkip > 0)
{
int bytesSkipped = (int)Math.Min(bytesToSkip, int.MaxValue);
stream.Read(new byte[bytesSkipped], 0, bytesSkipped);
bytesToSkip -= bytesSkipped;
}
// Read the required number of bytes
int bytesRead = stream.Read(buffer, 0, count);
if (bytesRead < count)
{
throw new EndOfStreamException("The stream has fewer bytes available than requested.");
}
return buffer;View on GitHub (pinned to cb5d9c429c)
Solutions
- If the stream is seekable, set stream.Position = index before calling GetBytes instead of relying on the skip logic.
- Read PE structures in file-offset order so the cursor only moves forward.
- Buffer the whole image into a MemoryStream/byte[] and index randomly rather than streaming.
- Catch ArgumentException and re-open the stream from the start for out-of-order access.
Example fix
// before
long bytesToSkip = index - currentPosition;
if (bytesToSkip < 0)
throw new ArgumentException("Offset is before the current position in the stream.");
// after — rewind when seekable
if (index < stream.Position)
{
if (stream.CanSeek) stream.Position = index;
else throw new ArgumentException("Offset is before the current position and stream is not seekable.");
} Defensive patterns
Strategy: validation
Validate before calling
if (index < stream.Position) {
if (stream.CanSeek) stream.Position = index;
else throw new ArgumentException("Cannot read backwards on a forward-only stream.");
} Type guard
static bool CanReadAt(Stream s, long index) => index >= s.Position || s.CanSeek;
Try / catch
try { bytes = stream.GetBytes(index, count); }
catch (ArgumentException) { stream.Position = index; bytes = stream.GetBytes(index, count); } Prevention
- Read PE structures in ascending file-offset order on forward-only streams.
- Prefer seekable MemoryStream/byte[] for random section access.
- Set stream.Position explicitly when CanSeek is true.
When it happens
Trigger: Calling GetBytes(stream, index, count) with an `index` smaller than stream.Position — e.g. requesting a section whose PointerToRawData is before where the cursor already advanced during header parsing, on a non-seekable or forward-only consumption.
Common situations: Parsing PE structures out of order (reading a later section then an earlier one) without rewinding; using a forward-only stream (network/decompressed) where Position only increases; an off-by-one or wrong offset computed for PointerToRawData.
Related errors
- The stream has fewer bytes available than requested.
- Section '{Header.Name}' incomplete.
- DOS signature not found.
- DOS header not found.
- DOS header incomplete.
AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13).
Data as JSON: /api/errors/5ceb4de16112427f.
Report an issue: GitHub.