schollz/croc · error · Error

Transfer size is too large

Error message

Transfer size is too large

What it means

validateSenderInfo() accumulates the total transfer size across all offered files and throws once the running sum stops being a safe integer (> 2^53-1 ≈ 9 PB). Beyond that bound, byte offsets and progress arithmetic in JavaScript lose precision, so the transfer cannot be tracked correctly.

Source

Thrown at web/src/protocol/metadata.ts:81

export function validateSenderInfo(info: SenderInfoWire): TransferOffer {
  if (info.SendingText) throw new Error("Text transfers are not supported yet");
  if (info.HashAlgorithm && info.HashAlgorithm !== "xxhash") {
    throw new Error(`Hash algorithm "${info.HashAlgorithm}" is not supported`);
  }

  const destinations = new Set<string>();
  const files: OfferedFile[] = [];
  let totalSize = 0;
  for (const wire of info.FilesToTransfer ?? []) {
    if (wire.sy) throw new Error("Symlink transfers are not supported in the browser");
    const normalized = normalizeFilePath(wire.fr ?? ".", wire.n ?? "");
    if (destinations.has(normalized.path)) {
      throw new Error(`Duplicate destination path: ${normalized.path}`);
    }
    destinations.add(normalized.path);
    const size = finiteSize(wire);
    totalSize += size;
    if (!Number.isSafeInteger(totalSize)) throw new Error("Transfer size is too large");
    files.push({
      ...normalized,
      size,
      hash: wire.h ? base64ToBytes(wire.h) : new Uint8Array(),
      modified: wire.m,
      mode: wire.md,
    });
  }

  const emptyFolders: string[] = [];
  for (const wire of info.EmptyFoldersToTransfer ?? []) {
    const folder = normalizeFolder(wire.fr ?? ".");
    if (destinations.has(folder)) {
      throw new Error(`Duplicate destination path: ${folder}`);
    }
    destinations.add(folder);
    emptyFolders.push(folder);
  }

View on GitHub (pinned to e25f1bdc04)

Solutions

  1. Split the transfer into several sends, each comfortably below 2^53 bytes total.
  2. If you operate a receiving service, cap accepted totalSize (e.g. 1 TB) before invoking validateSenderInfo-style logic so users get an actionable limit error.
  3. Never rewrite the guard to allow unsafe sums — downstream offset math will silently corrupt.
Defensive patterns

Strategy: validation

Validate before calling

const MAX_TOTAL = Number.MAX_SAFE_INTEGER; // ~9 PB hard ceiling
function totalWithinLimit(info: SenderInfoWire, cap = MAX_TOTAL): boolean {
  let sum = 0;
  for (const f of info.FilesToTransfer ?? []) {
    sum += f.s ?? 0;
    if (!(Number.isSafeInteger(sum)) || sum > cap) return false;
  }
  return true;
}

Try / catch

try {
  const offer = validateSenderInfo(info);
} catch (error) {
  if (error instanceof Error && error.message === "Transfer size is too large") {
    notifyUser("transfer exceeds browser-safe total size; split into multiple sends");
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: An offer whose summed file sizes exceed Number.MAX_SAFE_INTEGER — either a genuinely enormous multi-file transfer or a hostile peer declaring huge per-file sizes that individually pass finiteSize (each ≤ 2^53-1) but overflow in aggregate.

Common situations: Bulk-archival sends of petabyte-scale datasets; hostile metadata probing numeric limits; fuzzed offers with maximal 's' values; feeds that were meant to be size-limited but were not.

Related errors


AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15). Data as JSON: /api/errors/dbcf58ada559a228. Report an issue: GitHub.