oven-sh/bun · error · Error

size mismatch

Error message

size mismatch

What it means

The integrity hash recorded for a package does not match the tarball bytes that were downloaded. Verification happens in ExtractTarball::run before extraction (src/install/extract_tarball.rs:47-58) and while streaming the download (src/install/TarballStream.rs:1121); for GitHub/URL/local tarballs Bun deliberately computes and pins the hash in the lockfile so a compromised server cannot silently swap content (comment at extract_tarball.rs:62-65).

Source

Thrown at bench/copyfile/node.mitata.mjs:15

import { copyFileSync, statSync, writeFileSync } from "node:fs";
import { bench, run } from "../runner.mjs";

function runner(ready) {
  for (let size of [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]) {
    const rand = new Int32Array(size);
    for (let i = 0; i < size; i++) {
      rand[i] = (Math.random() * 1024 * 1024) | 0;
    }
    const dest = `/tmp/fs-test-copy-file-${((Math.random() * 10000000 + 100) | 0).toString(32)}`;
    const src = `/tmp/fs-test-copy-file-${((Math.random() * 10000000 + 100) | 0).toString(32)}`;
    writeFileSync(src, Buffer.from(rand.buffer), { encoding: "buffer" });
    const { size: fileSize } = statSync(src);
    if (fileSize !== rand.byteLength) {
      throw new Error("size mismatch");
    }
    ready(src, dest, new Uint8Array(rand.buffer));
  }
}
runner((src, dest, rand) =>
  bench(`copyFileSync(${rand.buffer.byteLength} bytes)`, () => {
    copyFileSync(src, dest);
    // const output = readFileSync(dest).buffer;

    // for (let i = 0; i < output.length; i++) {
    //   if (output[i] !== rand[i]) {
    //     throw new Error(
    //       "Files are not equal" + " " + output[i] + " " + rand[i] + " " + i
    //     );
    //   }
    // }
  }),
);

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Clear the cache and reinstall: `bun pm cache rm && bun install`
  2. For URL/GitHub tarballs pinned to a branch, re-record the hash: re-run `bun add <url-or-github-spec>` so the lockfile captures the current tarball
  3. Compare hashes out-of-band: `npm view <pkg> dist.integrity` vs. curl the tarball and compute its sha512
  4. If tampering is plausible, do NOT bypass the check: pin an exact version/commit and verify the artifact from the official registry

Example fix

// before (package.json): moving ref, hash drifts on every push
"ui-kit": "github:acme/ui-kit#main"

// after: immutable ref, lockfile hash stays valid
"ui-kit": "github:acme/ui-kit#1f0e3d8c2a7b94f6cc4e21c1d7f3a9b8"
Defensive patterns

Strategy: validation

Validate before calling

// Before promoting a URL/git tarball dep, confirm the bytes match what you will pin:
const res = Bun.spawnSync(["npm", "view", "your-pkg", "dist.integrity"], { stdout: "pipe" });
const pinned = Bun.file("bun.lock").text(); // or your recorded hash
console.log("registry integrity:", res.stdout.toString().trim());

Type guard

const isValidSRI = (s) => /^sha(1|256|384|512)-[A-Za-z0-9+/=]+$/.test(s ?? "");

Prevention

When it happens

Trigger: `bun install` with a lockfile whose pinned sha512/sha1 differs from the fetched artifact: registry mirror out of sync for the same version, a corrupted cache entry, a GitHub tarball re-generated for a moving ref (branch/HEAD) while the lockfile pins the old hash, or a yanked-and-republished package.

Common situations: Switching between registry mirrors that serve different bytes; using `github:owner/repo#main` style deps whose tarballs change; CI cache corruption; in rare cases actual supply-chain tampering.

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/91d7e8d0f2c153ad. Report an issue: GitHub.