schollz/croc · error · Error
Hash algorithm "${info.HashAlgorithm}" is not supported
Error message
Hash algorithm "${info.HashAlgorithm}" is not supported What it means
validateSenderInfo() accepts only the xxhash algorithm. If the offer's HashAlgorithm field is present and set to anything else (e.g. 'sha256', 'md5'), the client cannot verify chunk integrity because its wasm pipeline only implements xxhash, so the transfer is refused before any data flows.
Source
Thrown at web/src/protocol/metadata.ts:66
export function normalizeOutgoingFileName(value: string) {
// Go's unicode.IsPrint accepts ASCII space but rejects the other Unicode
// separator characters commonly inserted into filenames by macOS.
const compatible = value.replace(/\p{Z}+/gu, " ");
return normalizeFilePath(".", compatible).name;
}
function finiteSize(file: WireFileInfo) {
const size = file.s ?? 0;
if (!Number.isSafeInteger(size) || size < 0) {
throw new Error(`Invalid file size for ${file.n ?? "unnamed file"}`);
}
return size;
}
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,View on GitHub (pinned to e25f1bdc04)
Solutions
- Have the sender use a croc version whose HashAlgorithm is xxhash (the stock croc default).
- If a custom algorithm is mandatory for your deployment, implement it in the wasm verification pipeline first, then widen the check in validateSenderInfo.
- As a receiver, catch this error and tell the peer to update/downgrade to a compatible croc build.
Defensive patterns
Strategy: type-guard
Validate before calling
function isSupportedHash(info: SenderInfoWire): boolean {
return !info.HashAlgorithm || info.HashAlgorithm === "xxhash";
} Type guard
function hasCompatibleHash(info: SenderInfoWire): info is SenderInfoWire & { HashAlgorithm?: "xxhash" } {
return !info.HashAlgorithm || info.HashAlgorithm === "xxhash";
} Try / catch
try {
const offer = validateSenderInfo(info);
} catch (error) {
if (error instanceof Error && /Hash algorithm/.test(error.message)) {
notifyUser("sender uses an unsupported hash; ask them to use stock croc (xxhash)");
return;
}
throw error;
} Prevention
- Use stock croc builds whose HashAlgorithm is xxhash or absent.
- If you must support another algorithm, implement it in the wasm verifier before widening the check.
- Include HashAlgorithm in interop test matrices to catch version drift early.
When it happens
Trigger: A croc build or fork that negotiates a non-xxhash HashAlgorithm sends an offer to this client; or hand-crafted SenderInfoWire with HashAlgorithm: 'sha256'. An absent or 'xxhash' value passes.
Common situations: Peer running a modified/newer croc that switched the default hash algorithm; forked protocol variants; test fixtures copied from a different croc version; security scanners checking the strictness of algorithm negotiation.
Related errors
- Sender did not provide file metadata
- Remote filename must be a basename: ${nameValue}
- Text transfers are not supported yet
- Peer uses unsupported PAKE protocol version ${version ?? 0};
- Relay returned an invalid port list: ${banner}
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/dbb3c600f3eba527.
Report an issue: GitHub.