vercel/next.js · error

fixed key block too short

Error message

fixed key block too short

What it means

lookup_fixed_key_block requires a fixed-layout key block to be at least 6 bytes so it can read the entry count, key size, and header-type bytes. A shorter block cannot be parsed at all, so the layer reports it as corrupt rather than returning a lookup miss.

Solutions

  1. Delete the persistent cache directory and rebuild the cache.
  2. Avoid copying or snapshotting the cache directory while builds are running.
  3. Check the storage volume for hardware/filesystem errors.
  4. Report a reproducible case with the offending SST file to the Turbopack team.
Defensive patterns

Strategy: fallback

Try / catch

try {
  lookup(key);
} catch (e) {
  if (/fixed key block too short/.test(String(e))) {
    resetCache();
  } else throw e;
}

Prevention

When it happens

Trigger: A fixed-key SST key block shorter than 6 bytes read during a point lookup — truncated or corrupt block delivered by the block cache.

Common situations: Torn or partial writes to the Turbopack persistent cache; disk corruption; a cache directory copied while a build was writing to it.

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


AI-assisted analysis of vercel/next.js@34433fd12e (2026-09-20). Data as JSON: /api/errors/347ea02aa37fa81e. Report an issue: GitHub.

Appendix: source

Thrown at turbopack/crates/turbo-persistence/src/static_sorted_file.rs:640

        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],
        key_hash: u64,
        key: &K,
        layout: KeyBlockLayout,
        reader: ArcBlockCacheReader<'_>,
    ) -> Result<SstLookupResult> {
        ensure!(block.len() >= 6, "fixed key block too short");
        let entry_count = be::read_u24(&block[1..]) as usize;
        let key_size = be::read_u8(&block[4..]) as usize;
        let header_type = be::read_u8(&block[5..]);
        let FixedValueLayout {
            value_type,
            val_size,
            header_size,
        } = fixed_value_layout(block, header_type)?;
        let regions = FixedRegions::new(entry_count, layout, key_size, val_size);
        let entries = &block[header_size..];
        ensure!(
            entries.len() == regions.total_len(entry_count),
            "fixed key block for {entry_count} entries is the wrong size"
        );

        self.lookup_block_inner::<K, FIND_ALL>(entry_count, key_hash, key, layout, reader, |i| {
            get_fixed_key_entry(entries, i, regions, value_type)
        })

View on GitHub (pinned to 34433fd12e)