vercel/next.js · error
key block too short for
Error message
key block too short for {entry_count} entries What it means
After reading the entry count from a variable-key block's header, turbo-persistence checks that the remaining bytes are large enough to hold entry_count offset-table entries of key_block_table_stride(hash_len) bytes each. The block claims more entries than its byte length can hold, so it is corrupt or written with a mismatched layout.
Solutions
- Delete the persistent cache directory and let it regenerate.
- Clear the cache when upgrading or downgrading Next.js/Turbopack so on-disk formats always match the reader.
- Verify no concurrent writer is interleaving into the same cache directory.
- If reproducible on a fresh cache, report as a turbo-persistence layout bug.
Defensive patterns
Strategy: fallback
Try / catch
try {
lookup(key);
} catch (e) {
if (/key block too short for \d+ entries/.test(String(e))) {
resetCache();
} else throw e;
} Prevention
- Keep cache writer and reader on the same Turbopack version (clear cache on version switches).
- Prevent concurrent builds from writing to one cache directory.
- Rebuild the cache at the first sign of corruption rather than ignoring it.
When it happens
Trigger: A variable-key SST key block whose declared entry count times the table stride exceeds the block's data length — header/data mismatch from truncation or a format-version mismatch between writer and reader.
Common situations: Cache files produced by a different Turbopack version with a changed key-block table stride; partially written cache blocks after a crash.
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
- block of .sst is the last block but not an index block…
- 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
AI-assisted analysis of vercel/next.js@34433fd12e (2026-09-20).
Data as JSON: /api/errors/c8bdfce1a275c397.
Report an issue: GitHub.
Appendix: source
Thrown at turbopack/crates/turbo-persistence/src/static_sorted_file.rs:616
/// Looks up a key in a key block and the value in a value block.
///
/// If `FIND_ALL` is false, returns after finding the first match.
/// If `FIND_ALL` is true, collects all entries with the same key.
fn lookup_variable_key_block<K: QueryKey, const FIND_ALL: bool>(
&self,
block: &[u8],
key_hash: u64,
key: &K,
layout: KeyBlockLayout,
reader: ArcBlockCacheReader<'_>,
) -> Result<SstLookupResult> {
let hash_len = layout.hash_len();
ensure!(block.len() >= 4, "key block too short");
let entry_count = be::read_u24(&block[1..]) as usize;
let data = &block[4..];
let table_len = entry_count * key_block_table_stride(hash_len);
ensure!(
data.len() >= table_len,
"key block too short for {entry_count} entries"
);
let offsets = &data[..table_len];
let entries = &data[table_len..];
self.lookup_block_inner::<K, FIND_ALL>(entry_count, key_hash, key, layout, reader, |i| {
get_key_entry(offsets, entries, entry_count, i, hash_len)
})
}
/// Looks up a key in a fixed-size key block.
///
/// Fixed-size key blocks store entries at predictable offsets (no offset table),
/// enabling direct indexing during binary search.
fn lookup_fixed_key_block<K: QueryKey, const FIND_ALL: bool>(
&self,
block: &[u8],View on GitHub (pinned to 34433fd12e)