tinyhumansai/openhuman · error · anyhow::Error

Failed to load secret-store master key from keychain: {e} |

Error message

Failed to load secret-store master key from keychain: {e} | detail={}

What it means

Loading the secret-store master key from the OS keychain failed during encrypted-store initialization. This is the bootstrap step that obtains the 32-byte key guarding all at-rest secrets; a keychain read error (locked, missing backend, access denied) aborts the store. Legacy-file migration failures are deliberately tolerated nearby — this error is strictly the keychain read itself.

Source

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

            }
            Ok(crate::openhuman::security::keyring::MigrationOutcome::AlreadyMigrated)
            | Ok(crate::openhuman::security::keyring::MigrationOutcome::NoSourceFile) => {}
            Err(error) => {
                log::warn!(
                    "[security] failed to migrate legacy secret-store key from {}: {error} | detail={}",
                    self.key_path.display(),
                    error.diagnostic()
                );
            }
        }

        let hex_key = crate::openhuman::security::keyring::get_or_create_random(
            &user_id,
            KEYCHAIN_MASTER_KEY,
            KEY_LEN,
        )
        .map_err(|e| {
            anyhow::anyhow!(
                "Failed to load secret-store master key from keychain: {e} | detail={}",
                e.diagnostic()
            )
        })?;
        decode_key_hex(hex_key.trim())
    }

    /// Load the encryption key from keychain-backed storage, falling back to
    /// the legacy file path only in unit tests.
    ///
    /// The decoded key is cached process-wide keyed by `key_path`, so repeated
    /// callers (e.g. every `app_state_snapshot` poll) hit memory instead of
    /// disk/keychain lookup.
    ///
    /// The key bytes are wrapped in [`Zeroizing`] so every copy — the returned
    /// value, the cache entry, and any intermediate buffers — is wiped from
    /// memory on drop rather than lingering in the heap/swap/core-dumps.
    fn load_or_create_key(&self) -> Result<Zeroizing<Vec<u8>>> {

View on GitHub (pinned to 7491200858)

Solutions

  1. Unlock the OS keychain and retry
  2. Verify the keyring backend is available in this environment (headless/container contexts often lack one)
  3. Check keychain entry permissions for the app
  4. Read `{e}` diagnostic detail for the backend-specific cause
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at src/openhuman/security/keyring/encrypted_store.rs:239 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/232d8f9a179bfb48. Report an issue: GitHub.