schollz/croc · error · Error
Sender PAKE confirmation failed
Error message
Sender PAKE confirmation failed
What it means
Thrown by the recipient when the sender's pake-confirm token fails wasm confirmPeerKey — the cryptographic proof that both parties derived the same shared key did not verify. This means the negotiated keys differ, almost always because the PAKE inputs (passphrase, room, purpose, curve, identities) were not identical on both sides. The channel is deliberately not established.
Source
Thrown at web/src/protocol/client.ts:713
peerPake.b2,
PAKE_PURPOSE_TRANSFER,
room,
curve,
pake.bytes,
peerPake.b,
);
await sendControl(control, {
t: "pake-confirm",
v: PAKE_PROTOCOL_VERSION,
b: peerKeys.confirmationA,
});
const confirmationB = await receiveControl(control);
if (confirmationB.t !== "pake-confirm" || !confirmationB.b) {
throw new Error("Sender did not confirm the croc PAKE handshake");
}
requirePakeVersion(confirmationB.v);
if (!(await wasm().confirmPeerKey(peerKeys.confirmationB, confirmationB.b))) {
throw new Error("Sender PAKE confirmation failed");
}
key = peerKeys.key;
data = await openDataConnections(
settings,
room,
dataPorts(relay.banner),
signal,
);
await sendControl(control, {
t: "externalip",
m: relay.externalIP,
b: peerPake.b,
}, key);
const peerIP = await receiveControl(control, key);
if (peerIP.t !== "externalip") throw new Error("Sender did not secure the channel");
const fileInfo = await receiveControl(control, key);
if (fileInfo.t === "error") throw new Error(fileInfo.m || "Sender cancelled");View on GitHub (pinned to e25f1bdc04)
Solutions
- Regenerate and re-share the code phrase; both peers must enter the exact same string (validateSecret enforces printable ASCII >=6 chars, but equality is on the users)
- Verify codeComponents output (room + passphrase) is identical on both peers — log the room hash, not the secret
- Ensure PAKE_PURPOSE_TRANSFER and curve p256 are unchanged in any fork; both are hard-coded inputs to derivation
- If it persists with identical phrases, suspect wasm build skew and rebuild/upgrade both clients
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight both sides derive identical components before connecting
const { room, passphrase } = await wasm().codeComponents(secret);
// compare a hash of room+passphrase out-of-band (never send the secret itself)
const digest = await wasm().hashFinal(await wasm().hashInit()); // illustrative
Try / catch
catch (e) {
if (e instanceof Error && e.message === "Sender PAKE confirmation failed") {
// keys diverged: almost always a code-phrase mismatch; re-share the code and retry
}
throw e;
} Prevention
- Use copy-paste for code phrases; never retype unicode-prone strings
- Confirm both peers run identical client builds so PAKE purpose/curve/identity inputs match
- Treat confirmation failure as a credential problem first, a crypto bug only after identical phrases still fail
When it happens
Trigger: Different passphrases derived from slightly different code phrases; room string differs (e.g. code phrase parsed differently by peers); PAKE purpose ('peer-transfer') or curve ('p256') mismatch between implementations; corrupted confirmation bytes in transit; wasm engine version skew changing key derivation.
Common situations: Users mistype or variant-type the code phrase (trailing spaces, unicode look-alikes); one peer uses a croc build whose codeComponents parses rooms differently; forked clients changing the PAKE purpose string; bit corruption on the relay path (rare since encryption would usually fail earlier).
Related errors
- Recipient PAKE confirmation failed
- Sender did not complete the croc PAKE handshake
- Sender provided an invalid ${peerPake.b2.byteLength}-byte PA
- Sender did not confirm the croc PAKE handshake
- Peer uses unsupported PAKE protocol version ${version ?? 0};
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/c88a8e6b8ec88e0f.
Report an issue: GitHub.