vercel/next.js · error
block of .sst is the last block but not an index block…
Error message
block {} of {:08}.sst is the last block but not an index block (type {}) What it means
When parsing the final block of an SST file, turbo-persistence requires that the last block be the index block (type BLOCK_TYPE_INDEX). This error means the last block's type byte is something else, so the file's footer/index layout is corrupt or was written by an incompatible writer.
Solutions
- Delete the SST file or the whole persistent cache directory and rebuild the cache.
- Ensure the cache directory is not shared between different Turbopack/Next.js versions; clear it when switching versions.
- Check that writes to the cache volume complete cleanly (no abrupt shutdown, sufficient space).
- If it reproduces after a version change, report it with the file version metadata.
Defensive patterns
Strategy: fallback
Validate before calling
if (isSstFileTruncated(path)) { fs.rmSync(path, { force: true }); } Try / catch
try {
openCache(cacheDir);
} catch (e) {
if (/not an index block/.test(String(e))) {
fs.rmSync(cacheDir, { recursive: true, force: true });
openCache(cacheDir);
} else throw e;
} Prevention
- Clear the cache directory when upgrading or downgrading Next.js/Turbopack.
- Ensure clean shutdowns; interrupted writes corrupt the SST tail.
- Do not share one cache directory across versions or concurrent builds.
When it happens
Trigger: Reading a {:08}.sst file whose last block type byte does not equal BLOCK_TYPE_INDEX — truncated file tail, partially flushed write, or a file written by a different turbo-persistence version with a changed block format.
Common situations: Cache written by a newer/older Next.js or Turbopack version being read after an upgrade or downgrade; interrupted write leaving a partial block as the file tail.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- fixed key block for entries is the wrong size
- fixed key block too short
- index block of .sst is too short ( bytes)
- key block too short
- key block too short for
AI-assisted analysis of vercel/next.js@34433fd12e (2026-09-20).
Data as JSON: /api/errors/7d2c530fd03588cc.
Report an issue: GitHub.
Appendix: source
Thrown at turbopack/crates/turbo-persistence/src/static_sorted_file.rs:418
verify_checksum(meta, data, checksum, block_index)?;
ensure!(
data.len() >= INDEX_BLOCK_HEADER_SIZE,
"index block {} of {:08}.sst is too short ({} bytes)",
block_index,
meta.sequence_number,
data.len()
);
ensure!(
be::read_u8(data) == BLOCK_TYPE_INDEX,
"block {} of {:08}.sst is the last block but not an index block (type {})",
block_index,
meta.sequence_number,
be::read_u8(data)
);
let first_block = be::read_u16(&data[1..]);
let entry_bytes = &data[INDEX_BLOCK_HEADER_SIZE..];
ensure!(
entry_bytes.len().is_multiple_of(INDEX_BLOCK_ENTRY_SIZE),
"index block {} of {:08}.sst has {} trailing bytes past its last entry",
block_index,
meta.sequence_number,
entry_bytes.len() % INDEX_BLOCK_ENTRY_SIZE
);
let entries = match backing {
// Store a range, not the slice: `StaticSortedFile` owns the mmap these bytes live in.
#[cfg(feature = "mmap")]
StaticSortedFileBacking::Mmap(mmap) => {
let start = entry_bytes.as_ptr() as usize - mmap.as_ptr() as usize;
IndexEntries::Mmap(start..start + entry_bytes.len())
}
StaticSortedFileBacking::File { .. } => IndexEntries::Owned(entry_bytes.into()),
};
Ok(Self {
entries,View on GitHub (pinned to 34433fd12e)