atuinsh/atuin · error · SyncError

WrongKey

Error message

WrongKey

What it means

`SyncError::WrongKey` is returned by `check_key_against_index` when a record fetched from the sync server cannot be decrypted with the local encryption key (`record.decrypt(key)` errs). It means the key being used does not match the key the records were encrypted with — typically during `atuin login`/`sync` key verification.

Solutions

  1. Log in again supplying the correct original encryption key (from the machine that first ran `atuin register`, stored in ~/.local/share/atuin/key).
  2. Export the key from a working machine with `atuin key` and use it at login (`atuin login --key <key>`).
  3. If the key is truly lost, register a fresh account (accepting history loss) so all records re-encrypt under the new key.

Example fix

// before
atuin login --username me --password pw --key <wrong-key>
// after
atuin key   # on the original machine
atuin login --username me --password pw --key <correct-key-from-atuin-key>
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the local key decrypts an existing local record before syncing
let local_key = atuin_client::encryption::load_key()?;
// run `atuin key` on the original machine and compare before logging in

Try / catch

match sync::check_encryption_key().await {
    Some(SyncError::WrongKey) => eprintln!("Encryption key mismatch: re-login with the original key from `atuin key` on the registering machine"),
    Some(other) => eprintln!("sync check failed: {other:?}"),
    None => { /* key OK, proceed with sync */ }
}

Prevention

When it happens

Trigger: During `check_encryption_key`, a remote record is downloaded and `record.decrypt(key)` fails (crates/atuin-client/src/record/sync/mod.rs:223), producing `SyncError::WrongKey`. Triggered by logging in with an encryption key that differs from the one the account's records were encrypted with.

Common situations: Re-creating an account and reusing an old key; copying a key from a different atuin account; key file at ~/.local/share/atuin/key being regenerated or from another machine; typos when pasting the key during login.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19). Data as JSON: /api/errors/485878d4c0602ab7. Report an issue: GitHub.

Appendix: source

Thrown at crates/atuin-client/src/record/sync/mod.rs:223

        let sample = remote_index
            .hosts
            .iter()
            .flat_map(|(host, tags)| {
                tags.keys().map(move |tag| RecordSeriesKey::new(*host, tag.clone()))
            })
            // Plaintext series (packfile manifests) would fail decryption with any key, so they
            // can't be used to check whether the local key matches the remote.
            .find(|series| !series.tag.is_plaintext());

        let series = sample?;

        let record = match self.client.records(&series).one().await {
            Ok(Some(record)) => record,
            Ok(None) => return None,
            Err(e) => return Some(SyncError::RemoteRequestError { msg: e.to_string() }),
        };

        record.decrypt(key).err().map(|_| SyncError::WrongKey)
    }

    /// Fetch the remote's record status index.
    #[instrument(level = "trace", skip_all, err)]
    pub async fn record_status(&self) -> Result<RecordStatus, SyncError> {
        self.client
            .record_status()
            .await
            .map_err(|e| SyncError::RemoteRequestError { msg: e.to_string() })
    }

    #[instrument(level = "trace", skip_all, err)]
    pub async fn diff(&self) -> Result<(Vec<Diff>, RecordStatus), SyncError> {
        let local_index = self
            .store
            .status()
            .await
            .map_err(|e| SyncError::LocalStoreError { msg: e.to_string() })?;

View on GitHub (pinned to 900007c480)