Documentation / Reference

This page is the document protocol/error-codes.md of the project, rendered unchanged. If the page and the document differ, the document is right.

SyncEngine Protocol v1 — Error Codes

Numeric values carried in ERROR (field 1) and TRANSFER_CANCEL (field 2). Codes are stable once published; a removed code is never reassigned.

"Wire" indicates whether the code can be sent to a peer. Codes marked "local" are only reported to the local user or API, e.g. because the session can no longer carry encrypted messages.

CodeNameWireTypical use
Session / protocol (1–99)
1E_PROTOCOL_VERSIONyesHELLO.protocol_major mismatch or detected version downgrade
2E_PROTOCOL_VIOLATIONyesMalformed frame/CBOR, wrong stream, wrong direction, sequence error
3E_UNKNOWN_MESSAGEyesUnknown message type
4E_UNSUPPORTED_CRITICALyesUnknown critical capability
5E_FRAME_TOO_LARGEyesFrame length above effective max_frame_payload
6E_LIMIT_EXCEEDEDyesStream limit, capability floor, clipboard size
7E_TIMEOUTyesHandshake, session establishment, pairing confirmation
8E_DUPLICATE_SESSIONyesLosing session of a duplicate pair
Authentication / pairing (100–199)
100E_AUTH_FAILEDlocalNoise handshake or record authentication failure
101E_PEER_NOT_TRUSTEDyesIK initiator static key unknown or revoked; sent by the responder after completing the handshake. Also the fatal ERROR that ends the sessions of a peer that was revoked, and the IPC answer to transfer.send for a peer that is not trusted
110E_PAIRING_EXPIREDlocalJoiner could not reach an inviter accepting the code (TTL elapsed or code unknown); never sent, because an inviter no longer accepts XX after the TTL. Also reported to the inviter's frontend when its invitation ran out. From IPC minor 3 pairing.done may say why a relay did not lead to an inviter (ipc-v1.md §4.3)
111E_PAIRING_CONSUMEDyesCapability already used or cancelled. Locally also: another join of the same engine with the same URI recorded the code first
112E_PAIRING_PROOF_INVALIDyescap_proof mismatch
113E_PAIRING_COMMIT_MISMATCHyesRevealed n_R does not match sas_commit
114E_SAS_REJECTEDyesA user rejected the SAS
Transfer (200–299)
200E_TRANSFER_NOT_FOUNDyesResume of an unknown transfer. Non-final, not persisted
201E_TRANSFER_CONFLICTyesKnown transfer_id with different metadata
202E_TRANSFER_OFFSET_INVALIDyesGap, overlap, out-of-range data, premature FIN
203E_TRANSFER_HASH_MISMATCHyesFinal verification failed
204E_SOURCE_CHANGEDyesSender detected a modified source file
205E_CANCELLEDyesUser-initiated cancellation. Locally also a cancelled or replaced pairing invitation
206E_TRANSFER_EXPIREDyesPending offer or incomplete transfer expired
207E_STREAM_SUPERSEDEDyesNon-fatal ERROR closing an older stream when the same transfer is re-opened on a new one
Storage / policy (300–399)
300E_INSUFFICIENT_SPACEyesFree-space check failed
301E_QUOTA_EXCEEDEDyesPer-peer quota or pending-transfer limit; in the browser engine also a full file pool. Non-final, not persisted; the sender re-offers later
302E_STORAGE_FAILUREyesI/O error on the receiver. Locally also a failure to commit the joiner's used-code record before XX message 3 (protocol-v1.md §10.1), and also every refusal of a start because of the key store or state.db (a newer state.db is E_STATE_VERSION) and every other failure or refusal of a reset (the lock and an invalid config.toml have their own codes below)
303E_POLICY_DENIEDyesAcceptance policy or user rejected. Locally also (IPC): engine.shutdown on an embedded engine, pair.invite and pair.cancel where the pairing rules refuse them, settings.set of a setting fixed by a command-line option, clip.send while clipboard_sync is off, in the browser engine pair.join for a pairing URI whose relay origin the user neither entered nor confirmed (checked after the URI and the used-code checks, and it consumes no code), and in the browser engine in session mode relay.provision (refused before any request)
Local only (32768+)
32768E_STATE_LOCKEDlocalAnother engine instance owns the state directory. The desktop app does not treat it as a failure when the owner is a daemon of the same user: it attaches. Also the answer of a reset while an engine holds the lock
32769E_ENGINE_UNAVAILABLElocalCLI cannot reach or start an engine
32770E_IPC_VERSIONlocalCLI and engine IPC versions incompatible
32771E_IPC_UNKNOWN_METHODlocalIPC method ID not known to the engine
32772E_IPC_INVALID_PARAMSlocalIPC params do not match the method schema
32773E_NOT_FOUNDlocalPeer, pairing handle, transfer or (browser engine) source token referenced via IPC does not exist
32774E_STATE_VERSIONlocalstate.db schema is newer than the engine supports; in the browser engine also a key record of a newer format than the build understands. Never answered with an offer to reset: the data is intact and a newer build reads it
32775E_CONFIG_INVALIDlocalconfig.toml cannot be read: not valid TOML, a key that the engine does not know, a value of the wrong type or outside its range, or a secret-like key. The start is refused; the message names the file and the key, never the value. It is a start-up error of the process that tried to start the engine (CLI, daemon, desktop app) or to select the key store for a reset and does not occur in an IPC answer

All TRANSFER_CANCEL reasons are final for the transfer_id except E_TRANSFER_NOT_FOUND and E_QUOTA_EXCEEDED. Pausing, including pauses caused by temporary conditions such as a full disk, uses TRANSFER_PAUSE, not a cancel code.

Unknown codes received from a peer MUST be treated as generic failures of their range (e.g. an unknown 2xx code as a failed transfer) and MUST NOT cause a protocol error.