BloopAI/vibe-kanban · critical
Server proof verification failed.
Error message
Server proof verification failed.
What it means
During PAKE-based relay host pairing, pairRelayHost runs a SPAKE2 enrollment with the relay backend; after the finish step it verifies the server's proof against the derived shared key. This Error is thrown when verifyServerProof returns false, meaning the server's server_proof_b64 does not match what the client expects — the server could not prove it derived the same shared secret (or the messages were tampered with / mismatched protocol versions).
Source
Thrown at packages/web-core/src/shared/dialogs/settings/settings/useRelayRemoteHostMutations.ts:96
client_id: relayClientIdentity.clientId,
client_name: relayClientIdentity.clientName,
client_browser: relayClientIdentity.clientBrowser,
client_os: relayClientIdentity.clientOs,
client_device: relayClientIdentity.clientDevice,
public_key_b64: publicKeyB64,
client_proof_b64: clientProofB64,
}
);
const serverProofValid = await verifyServerProof(
sharedKey,
startData.enrollment_id,
publicKeyBytes,
finishData.server_public_key_b64,
finishData.server_proof_b64
);
if (!serverProofValid) {
throw new Error('Server proof verification failed.');
}
await savePairedRelayHost({
host_id: hostId,
host_name: hostName,
client_id: relayClientIdentity.clientId,
client_name: relayClientIdentity.clientName,
signing_session_id: finishData.signing_session_id,
public_key_b64: publicKeyB64,
private_key_jwk: privateKeyJwk,
server_public_key_b64: finishData.server_public_key_b64,
paired_at: new Date().toISOString(),
});
}
export function useRelayRemoteHostsQuery() {
return {
queryKey: RELAY_REMOTE_HOSTS_QUERY_KEY,View on GitHub (pinned to 4deb7eca8f)
Solutions
- Re-enter the pairing code carefully (or regenerate it on the host) and retry the pairing flow
- Verify the relay backend and the client are on compatible versions — upgrade the older side
- Check that no proxy/HTTPS interceptor is rewriting or caching the enrollment responses
- Clear stored paired-host state and start a fresh pairing session
Example fix
// before
const serverProofValid = await verifyServerProof(
sharedKey, startData.enrollment_id, publicKeyBytes,
finishData.server_public_key_b64, finishData.server_proof_b64
);
if (!serverProofValid) {
throw new Error('Server proof verification failed.');
}
// after
const serverProofValid = await verifyServerProof(
sharedKey, startData.enrollment_id, publicKeyBytes,
finishData.server_public_key_b64, finishData.server_proof_b64
);
if (!serverProofValid) {
throw new Error(
`Server proof verification failed for host ${hostId} ` +
'(check that the pairing code matches and host/client relay versions are compatible).'
);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before pairing: ensure code normalization matches and host exists
const normalized = normalizedCode.trim().replace(/[-\s]/g, '').toUpperCase();
if (normalized.length === 0) throw new Error('Pairing code is empty');
const hosts = await listRelayHosts();
if (!hosts.some((h) => h.id === hostId)) throw new Error('Unknown host'); Type guard
function isPairingFailure(e: unknown): e is Error & { step: 'server-proof' } {
return e instanceof Error && e.message.includes('Server proof verification failed');
} Try / catch
try {
await pairRelayHost({ hostId, hostName, normalizedCode });
} catch (e) {
if (isPairingFailure(e)) {
// Do NOT save the host; prompt user to re-enter the code and retry.
showPairingError('Pairing code mismatch or incompatible host version. Please retry.');
}
} Prevention
- Always regenerate a fresh pairing code instead of reusing an old one after a failure
- Keep relay backend and client versions in lockstep
- Never bypass or log the server proof check — it is the server-authentication step of PAKE
- Avoid proxies/interceptors that can alter enrollment payloads during pairing
When it happens
Trigger: Calling usePairRemoteCloudHostMutation with a hostId/hostName/normalizedCode where finishRelaySpake2Enrollment returns a server proof that fails verification: wrong or mistyped enrollment code variant, mismatched relay backend/client SPAKE2 implementations or versions, corrupted/intercepted server_message data, or pairing against a host whose session state expired between start and finish.
Common situations: Typo in the pairing code (code normalized differently on the two sides); pairing an older host running an incompatible relay protocol version; a man-in-the-middle or misconfigured relay proxy altering payloads; race where the enrollment session on the relay expired before finish was called.
Related errors
- This host is not paired with your browser. Pair it in Relay
- This host pairing is outdated. Re-pair it in Relay settings.
- No peer key found for signing session {}
- Not authenticated
- (dynamic: extractErrorMessage(response, fallbackMessage))
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/3e9fad2182a3e04b.
Report an issue: GitHub.