moonD4rk/HackBrowserData · error
abe: read Local State: %w
Error message
abe: read Local State: %w
What it means
loadEncryptedKey reads Chrome's 'Local State' JSON file to extract os_crypt.app_bound_encrypted_key. This error wraps an os.ReadFile failure, meaning the Local State file could not be opened or read (missing file, permission denied, locked, etc.).
Source
Thrown at masterkey/abe_windows.go:76
inj := &injector.Reflective{}
key, err := inj.Inject(exePath, pl, env)
if err != nil {
return nil, fmt.Errorf("abe: inject into %s: %w", exePath, err)
}
if len(key) != 32 {
return nil, fmt.Errorf("abe: unexpected key length %d (want 32)", len(key))
}
log.Infof("abe: retrieved %s master key via reflective injection", browserKey)
return key, nil
}
func loadEncryptedKey(localStatePath string) ([]byte, error) {
if localStatePath == "" {
return nil, errNoABEKey
}
data, err := os.ReadFile(localStatePath)
if err != nil {
return nil, fmt.Errorf("abe: read Local State: %w", err)
}
raw := gjson.GetBytes(data, "os_crypt.app_bound_encrypted_key")
if !raw.Exists() {
return nil, errNoABEKey
}
decoded, err := base64.StdEncoding.DecodeString(raw.String())
if err != nil {
return nil, fmt.Errorf("abe: base64 decode: %w", err)
}
if len(decoded) <= len(appbPrefix) {
return nil, fmt.Errorf("abe: encrypted key too short: %d bytes", len(decoded))
}
for i, b := range appbPrefix {
if decoded[i] != b {
return nil, fmt.Errorf("abe: unexpected prefix: got %q, want %q",
decoded[:len(appbPrefix)], appbPrefix)View on GitHub (pinned to 0503d04d7a)
Solutions
- Verify localStatePath points at <user data dir>/Local State for the correct profile and user.
- Check file permissions / run with the rights needed to read the target profile.
- Close Chrome (or copy the file first) if the file is locked by a running browser instance.
- If the file genuinely doesn't exist, treat this as errNoABEKey and fall back to a non-ABE decryption path instead of failing.
Example fix
// before
key, err := RetrieveKey(exePath, localStatePath)
// after - pre-check the file before attempting ABE
if _, err := os.Stat(localStatePath); err != nil {
log.Warnf("Local State not readable at %s: %v; skipping ABE", localStatePath, err)
return fallbackDecrypt()
}
key, err := RetrieveKey(exePath, localStatePath) Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(localStatePath)
if err != nil {
return fmt.Errorf("Local State not accessible at %s: %w", localStatePath, err)
}
if info.IsDir() {
return fmt.Errorf("%s is a directory, expected the Local State file", localStatePath)
} Try / catch
key, err := RetrieveKey(exePath, localStatePath)
if err != nil {
if errors.Is(err, os.ErrNotExist) || errors.Is(err, os.ErrPermission) {
log.Warnf("cannot read Local State: %v; skipping ABE", err)
return fallbackDecrypt()
}
return err
} Prevention
- Resolve the profile path from the browser's actual user-data directory instead of hardcoding it.
- Pre-flight os.Stat on the Local State path before invoking ABE extraction.
- Copy the file when Chrome is running, since it may hold locks on Windows.
When it happens
Trigger: Calling RetrieveKey (which calls loadEncryptedKey) with a localStatePath pointing to a nonexistent, unreadable, or locked 'Local State' file, or when Chrome is running and holds an exclusive lock on the profile.
Common situations: Wrong profile path passed in (e.g. pointing at the wrong user data dir); running without permissions to read another user's profile; Chrome running and file locked on Windows; empty path (though empty path short-circuits to errNoABEKey first).
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- abe: Local State has no app_bound_encrypted_key
- seek to start: %w
- ReadFile: %w
- abe: unexpected key length %d (want 32)
- abe: base64 decode: %w
AI-assisted analysis of moonD4rk/HackBrowserData@0503d04d7a (2026-09-06).
Data as JSON: /api/errors/21d373d42428396f.
Report an issue: GitHub.