git-ecosystem/git-credential-manager · error · InteropException
ErrorSecInvalidKeychain
ErrorSecInvalidKeychain
Error message
The keychain is not valid.
What it means
Thrown by SecurityFramework.ThrowIfError when a Security.framework call returns errSecInvalidKeychain (-25295): the keychain reference or path is not a valid keychain. Unlike -25294 (keychain absent), this means the keychain object exists but is malformed, corrupted, wrong format, or unusable by the Security framework. The library converts the OS status into a descriptive InteropException.
Solutions
- Repair the keychain: open Keychain Access and run Keychain First Aid, or `security verify-keychain` / recreate the keychain and re-import items
- Confirm the default keychain is the correct file: `security default-keychain` and point it back to ~/Library/Keychains/login.keychain-db
- Restore the keychain from Time Machine backup or re-create it (`security create-keychain`) and let apps re-store credentials
- Log out/in after recreating the keychain so the securityd session picks up the new default keychain
Example fix
// before # keychain corrupted -> errSecInvalidKeychain security default-keychain ~/Library/Keychains/old-broken.keychain // after security create-keychain -p "" ~/Library/Keychains/login.keychain-db security default-keychain ~/Library/Keychains/login.keychain-db security unlock-keychain ~/Library/Keychains/login.keychain-db
Defensive patterns
Strategy: try-catch
Validate before calling
using System;
using System.Diagnostics;
static bool KeychainIsValid(string keychainPath)
{
var psi = new ProcessStartInfo("security", $"verify-keychain {keychainPath}")
{
UseShellExecute = false
};
using var p = Process.Start(psi);
p.WaitForExit();
return p.ExitCode == 0;
}
if (!KeychainIsValid("~/Library/Keychains/login.keychain-db"))
{
// repair/recreate the keychain before performing keychain operations
} Try / catch
try
{
keychain.Get(service, account);
}
catch (InteropException ex) when (ex.ErrorCode == -25295) // errSecInvalidKeychain
{
// Keychain corrupt/invalid: repair or recreate, then retry or fall back
}
Prevention
- Run `security verify-keychain` on keychain files restored or copied between machines
- Recreate the keychain rather than using a repaired-but-suspicious file when corruption is detected
- Don't copy keychain files across users or macOS versions; re-import items instead
- Catch error code -25295 and fall back to an alternate ICredentialStore until the keychain is repaired
When it happens
Trigger: Any MacOSKeychain operation whose underlying SecKeychain* call fails with OS status -25295 and is passed to ThrowIfError — e.g. finding, adding, updating, or deleting generic passwords against a keychain that the framework considers invalid.
Common situations: Corrupted login.keychain-db after disk issues or interrupted writes, keychain files created/copied from another macOS version or user, a path pointing to a non-keychain file, or older keychain formats after macOS upgrades.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- ErrorSecNoSuchKeychain
- ErrorSecAuthFailed
- ErrorSecDuplicateItem
- ErrorSecItemNotFound
- ErrorSecInteractionNotAllowed
AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11).
Data as JSON: /api/errors/6c3a04182a0da5bf.
Report an issue: GitHub.
Appendix: source
Thrown at src/Core/Interop/MacOS/Native/SecurityFramework.cs:144
public const int ErrorSecNoSuchKeychain = -25294;
public const int ErrorSecInvalidKeychain = -25295;
public const int ErrorSecAuthFailed = -25293;
public const int ErrorSecDuplicateItem = -25299;
public const int ErrorSecItemNotFound = -25300;
public const int ErrorSecInteractionNotAllowed = -25308;
public const int ErrorSecInteractionRequired = -25315;
public const int ErrorSecNoSuchAttr = -25303;
public static void ThrowIfError(int error, string defaultErrorMessage = "Unknown error.")
{
switch (error)
{
case OK:
return;
case ErrorSecNoSuchKeychain:
throw new InteropException("The keychain does not exist.", error);
case ErrorSecInvalidKeychain:
throw new InteropException("The keychain is not valid.", error);
case ErrorSecAuthFailed:
throw new InteropException("Authorization/Authentication failed.", error);
case ErrorSecDuplicateItem:
throw new InteropException("The item already exists.", error);
case ErrorSecItemNotFound:
throw new InteropException("The item cannot be found.", error);
case ErrorSecInteractionNotAllowed:
throw new InteropException("Interaction with the Security Server is not allowed.", error);
case ErrorSecInteractionRequired:
throw new InteropException("User interaction is required.", error);
case ErrorSecNoSuchAttr:
throw new InteropException("The attribute does not exist.", error);
default:
throw new InteropException(defaultErrorMessage, error);
}
}
}
View on GitHub (pinned to e8ce762cd0)