tinyhumansai/openhuman · error · anyhow::Error

Encrypted value too short (missing nonce)

Error message

Encrypted value too short (missing nonce)

What it means

A value carrying the `enc2:` prefix decoded to a blob shorter than the 12-byte nonce alone. The decryptor splits nonce from ciphertext at a fixed offset; a too-short blob means the stored ciphertext is truncated or corrupt — the size guard fires before any decryption is attempted.

Source

Thrown at src/openhuman/security/keyring/encrypted_store.rs:147

            let plaintext = self.decrypt_legacy_xor(hex_str)?;
            let migrated = self.encrypt(&plaintext)?;
            Ok((plaintext, Some(migrated)))
        } else {
            // Plaintext — no migration needed
            Ok((value.to_string(), None))
        }
    }

    /// Check if a value uses the legacy `enc:` format that should be migrated.
    pub fn needs_migration(value: &str) -> bool {
        value.starts_with("enc:")
    }

    /// Decrypt using ChaCha20-Poly1305 (current secure format).
    fn decrypt_chacha20(&self, hex_str: &str) -> Result<String> {
        let blob =
            hex_decode(hex_str).context("Failed to decode encrypted secret (corrupt hex)")?;
        anyhow::ensure!(
            blob.len() > NONCE_LEN,
            "Encrypted value too short (missing nonce)"
        );

        let (nonce_bytes, ciphertext) = blob.split_at(NONCE_LEN);
        let nonce = Nonce::from_slice(nonce_bytes);
        let key_bytes = self.load_or_create_key()?;
        let key = Key::from_slice(&key_bytes);
        let cipher = ChaCha20Poly1305::new(key);

        let plaintext_bytes = cipher
            .decrypt(nonce, ciphertext)
            .map_err(|_| anyhow::anyhow!("Decryption failed — wrong key or tampered data"))?;

        String::from_utf8(plaintext_bytes)
            .context("Decrypted secret is not valid UTF-8 — corrupt data")
    }

View on GitHub (pinned to 7491200858)

Solutions

  1. Check whether the stored value was truncated (column limits, manual edit)
  2. Restore the secret from its original source and re-store it
  3. If the record is unrecoverable, delete and re-create the credential
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at src/openhuman/security/keyring/encrypted_store.rs:147 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/08f1c302e5623e8f. Report an issue: GitHub.