denoland/deno · error
An attempt was made to move the file pointer before the begi
Error message
An attempt was made to move the file pointer before the beginning of the file.
What it means
Raised by `FileBackedVfsFile::seek` when a `SeekFrom::End(offset)` call would place the read pointer before byte 0: the negative offset's magnitude exceeds the file's length. The VFS rejects it with `io::ErrorKind::PermissionDenied` (the classic Windows `ERROR_NEGATIVE_SEEK` message) instead of letting the position underflow.
Source
Thrown at cli/rt/file_system.rs:1334
}
pub struct FileBackedVfsFile {
file: VirtualFile,
pos: RefCell<u64>,
vfs: Arc<FileBackedVfs>,
}
impl FileBackedVfsFile {
pub fn seek(&self, pos: SeekFrom) -> std::io::Result<u64> {
match pos {
SeekFrom::Start(pos) => {
*self.pos.borrow_mut() = pos;
Ok(pos)
}
SeekFrom::End(offset) => {
if offset < 0 && -offset as u64 > self.file.offset.len {
let msg = "An attempt was made to move the file pointer before the beginning of the file.";
Err(std::io::Error::new(
std::io::ErrorKind::PermissionDenied,
msg,
))
} else {
let mut current_pos = self.pos.borrow_mut();
*current_pos = if offset >= 0 {
self.file.offset.len - (offset as u64)
} else {
self.file.offset.len + (-offset as u64)
};
Ok(*current_pos)
}
}
SeekFrom::Current(offset) => {
let mut current_pos = self.pos.borrow_mut();
if offset >= 0 {
*current_pos += offset as u64;
} else if -offset as u64 > *current_pos {View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Clamp the offset to the file length: seek to `-Math.min(n, len)` after reading `len` from `file.stat()`.
- Use `SeekFrom::Start` / `Deno.SeekMode.Start` when the absolute target position is known.
- Validate input file size before running seek-based parsing and reject truncated files early.
Example fix
// before
await file.seek(-4096, Deno.SeekMode.End); // throws if file < 4096 bytes
// after
const { size } = await file.stat();
await file.seek(-Math.min(4096, size), Deno.SeekMode.End); Defensive patterns
Strategy: validation
Validate before calling
// before any negative End seek
const { size } = await file.stat();
const safe = Math.min(requestedBackstep, size);
await file.seek(-safe, Deno.SeekMode.End); Try / catch
try {
await file.seek(-n, Deno.SeekMode.End);
} catch (err) {
if (err instanceof Deno.errors.PermissionDenied) { /* clamp and retry once */ }
else throw err;
} Prevention
- Never assume file length; always read size from stat before relative seeks
- Prefer absolute SeekMode.Start positions in parsers
- Treat seek-past-start as malformed input and report the file/offset in the error
When it happens
Trigger: Calling `file.seek(SeekFrom::End(-n))` (Rust) or `file.seek(-n, Deno.SeekMode.End)` (JS) where n is greater than the file's byte length, on a file opened from the embedded VFS of a compiled binary. Any negative offset on an empty file also triggers it.
Common situations: Rewinding a fixed block size (e.g. seek -4096 to re-read a footer) on files smaller than that block; ported parsers that assume seek-before-start clamps to 0; truncated input files.
Related errors
- path not found (not dir): {}
- path not found (entry missing): {}
- unexpected EOF
- Unhandled scenario where a duplicate entry was found: {:?}
- Import map not found in eszip: {}
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/78e72522c1e9e86d.
Report an issue: GitHub.