moonD4rk/HackBrowserData · error
open keychain: %w
Error message
open keychain: %w
What it means
loadKeychainRecords fails to open the macOS login keychain via keychainbreaker.Open() and wraps the cause with "open keychain: %w". This is the first step of the keychain-based retriever; nothing can proceed without an open keychain handle.
Source
Thrown at masterkey/retriever_darwin.go:61
r.records, r.err = DecryptKeychainRecords()
})
if r.err != nil {
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.View on GitHub (pinned to 0503d04d7a)
Solutions
- Verify ~/Library/Keychains/login.keychain-db exists and is readable by the current user
- Open Keychain Access and repair/unlock the keychain to rule out corruption
- Check you are running as the user who owns the keychain, not root or another account
- Follow the wrapped cause (errors.Unwrap) for the specific OS-level reason
Example fix
// before
keychain := os.Getenv("HOME") + "/Library/Keychains/login.keychain-db"
// after
keychain := os.Getenv("HOME") + "/Library/Keychains/login.keychain-db"
if fi, err := os.Stat(keychain); err != nil || fi.IsDir() {
return nil, fmt.Errorf("keychain db not available at %s", keychain)
} Defensive patterns
Strategy: validation
Validate before calling
kcPath := filepath.Join(os.Getenv("HOME"), "Library", "Keychains", "login.keychain-db")
if _, err := os.Stat(kcPath); err != nil {
return fmt.Errorf("keychain db missing: %w", err)
} Type guard
func keychainExists() bool {
_, err := os.Stat(filepath.Join(os.Getenv("HOME"), "Library/Keychains/login.keychain-db"))
return err == nil
} Try / catch
key, err := retriever.RetrieveKey(hints)
if err != nil && strings.HasPrefix(err.Error(), "open keychain:") {
return nil, fmt.Errorf("cannot access login keychain: %w", err)
} Prevention
- Run under the macOS user who owns the keychain, not root
- Confirm login.keychain-db exists before invoking the retriever
- Repair corrupted keychains via Keychain Access first
When it happens
Trigger: Calling KeychainPasswordRetriever.RetrieveKey with a non-empty password when keychainbreaker.Open() returns an error (keychain database missing, corrupted, or unreadable).
Common situations: login.keychain-db moved or deleted, running as a different user whose keychain path doesn't exist, filesystem permission problems, or corrupted keychain after a failed macOS upgrade.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
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/c488a55c23dd05ac.
Report an issue: GitHub.