moonD4rk/HackBrowserData · error
unlock keychain: %w
Error message
unlock keychain: %w
What it means
The keychain opened successfully but kc.Unlock(keychainbreaker.WithPassword(password)) failed; the error is wrapped as "unlock keychain: %w". Unlocking the login keychain requires the correct user login password.
Source
Thrown at masterkey/retriever_darwin.go:64
log.Debugf("gcoredump: %v", r.err)
return nil, nil //nolint:nilerr // intentional silent fallthrough
}
key, err := findStorageKey(r.records, hints.KeychainLabel)
if err != nil {
log.Debugf("gcoredump: %v", err)
return nil, nil //nolint:nilerr // intentional silent fallthrough
}
return key, nil
}
func loadKeychainRecords(password string) ([]keychainbreaker.GenericPassword, error) {
kc, err := keychainbreaker.Open()
if err != nil {
return nil, fmt.Errorf("open keychain: %w", err)
}
if err := kc.Unlock(keychainbreaker.WithPassword(password)); err != nil {
return nil, fmt.Errorf("unlock keychain: %w", err)
}
return kc.GenericPasswords()
}
func findStorageKey(records []keychainbreaker.GenericPassword, storage string) ([]byte, error) {
for _, rec := range records {
if rec.Account == storage {
return darwinParams.deriveKey(rec.Password), nil
}
}
return nil, fmt.Errorf("%q: %w", storage, errStorageNotFound)
}
// KeychainPasswordRetriever unlocks login.keychain-db with the macOS login password (no root).
// Records are cached once and reused across browsers.
type KeychainPasswordRetriever struct {
Password string
View on GitHub (pinned to 0503d04d7a)
Solutions
- Confirm the Password field matches the current macOS login password of the keychain owner
- Test the password manually: unlock the keychain in Keychain Access or via `security unlock-keychain`
- If the keychain password differs from the login password, supply the keychain-specific password
- Ensure the keychain is not locked: `security show-keychain-info login.keychain-db`
Example fix
// before
r := &masterkey.KeychainPasswordRetriever{Password: "password123"}
// after
pw := os.Getenv("USER_LOGIN_PASSWORD")
if pw == "" {
return nil, errors.New("USER_LOGIN_PASSWORD not set")
}
r := &masterkey.KeychainPasswordRetriever{Password: pw} Defensive patterns
Strategy: validation
Validate before calling
if r.Password == "" {
return errors.New("keychain password required")
}
// optional pre-check
cmd := exec.Command("security", "unlock-keychain", "-p", r.Password)
if err := cmd.Run(); err != nil {
return fmt.Errorf("password rejected: %w", err)
} Type guard
func (r *masterkey.KeychainPasswordRetriever) Configured() bool {
return r.Password != ""
} Try / catch
key, err := r.RetrieveKey(hints)
if err != nil && strings.HasPrefix(err.Error(), "unlock keychain:") {
return nil, errors.New("wrong login password for keychain")
} Prevention
- Source the login password from a validated secure input
- Verify the password with `security unlock-keychain` before library use
- Handle password changes after macOS account password rotation
When it happens
Trigger: KeychainPasswordRetriever.RetrieveKey with a Password that is empty-check-passed but wrong, or when the keychain is locked and cannot be unlocked with the supplied password.
Common situations: User supplied the login password of a different account, the password was changed recently and the keychain kept the old one, or automation runs headless where the UI unlock prompt can't be answered.
Related errors
- requires root privileges
- keychain gcore dump not built in (rebuild with -tags keychai
- not found in credential store
- read keychain: %w
- tried %d candidates, none unlocked keychain
AI-assisted analysis of moonD4rk/HackBrowserData@0503d04d7a (2026-09-06).
Data as JSON: /api/errors/fdb57050b423736e.
Report an issue: GitHub.