git-ecosystem/git-credential-manager · error · InteropException
ErrorSecInteractionRequired
ErrorSecInteractionRequired
Error message
User interaction is required.
What it means
InteropException thrown by SecurityFramework.ThrowIfError when the macOS Security framework returns errSecInteractionRequired (-25315). It means the operation can only succeed if the user is prompted (e.g. to unlock the keychain, authorize access, or satisfy an authentication context), but the call was made in a way that no prompt was shown. Unlike errSecInteractionNotAllowed, the request itself is valid; a UI round-trip is required to proceed.
Solutions
- Allow Security Server UI for the call (remove kSecUseAuthenticationUIDisallow; use Allow or Failover so the prompt appears).
- Prompt the user deliberately: run the operation from a foreground, UI-capable context after informing the user why the keychain prompt appears.
- If user presence is not actually required, recreate the item without kSecAccessControlUserPresence/biometry flags so reads succeed non-interactively.
- Retry the operation after the user completes authentication (e.g. re-call after the Touch ID / unlock dialog succeeds).
- For background/daemons, use items without user-presence ACL, or cache an unlocked session via SecKeychainUnlock with stored credentials.
Example fix
// before: silent query of a user-presence-protected item throws
var query = new SecQueryDictionary(service).AsDictionary();
err = SecItemCopyMatching(query, out result);
SecurityFramework.ThrowIfError(err); // -25315: needs a user prompt
// after: perform the call where UI is allowed and retry once the user authenticates
query[kSecUseAuthenticationUI] = kSecUseAuthenticationUIAllow;
err = SecItemCopyMatching(query, out result);
if (err == ErrorSecInteractionRequired)
{
ShowExplainUnlockDialog(); // user completes Touch ID / password prompt
err = SecItemCopyMatching(query, out result); // retry
}
SecurityFramework.ThrowIfError(err); Defensive patterns
Strategy: retry
Validate before calling
// Detect items that require user presence before attempting non-interactive access
bool requiresUserPresence = query.ContainsKey(kSecAttrAccessControl);
if (requiresUserPresence && runningHeadless)
{
throw new InvalidOperationException("Item requires user interaction; run in a UI session or store the item without kSecAccessControl.");
} Type guard
static bool IsSecInteractionRequired(InteropException ex) => ex.ErrorCode == -25315; // errSecInteractionRequired
Try / catch
try
{
credential = ReadProtectedCredential(query);
}
catch (InteropException ex) when (ex.ErrorCode == -25315)
{
// A user prompt is mandatory: surface the request to the UI layer and retry once.
await uiService.ShowAuthenticationPromptAsync();
credential = ReadProtectedCredential(query); // single retry after user authenticated
} Prevention
- Don't disable Security UI (kSecUseAuthenticationUIDisallow) unless you know the item never requires consent.
- Only set kSecAccessControl user-presence/biometry flags on items that genuinely need them; store service-level tokens without them.
- Call keychain APIs from a foreground UI context after startup completes, not from silent background tasks that cannot show prompts.
- Always allow exactly one retry after user authentication completes; avoid infinite prompt loops.
- For automated environments, provision duplicates of secrets without access-control flags in a separate keychain.
When it happens
Trigger: SecItemCopyMatching/SecKeychainFindGenericPassword on an item whose ACL or kSecAccessControl policy requires user consent (Touch ID, device passcode, re-authentication) without kSecUseAuthenticationUI set appropriately; first access to a locked keychain item where authorization UI was suppressed; operations needing authorization rights that must be acquired interactively.
Common situations: Touch ID / Apple Watch-protected items accessed from a context where the prompt cannot display; apps calling keychain APIs during app startup before a window is available; automated tests hitting items configured with user-presence requirement; access-control items queried with UI explicitly disabled then failing because interaction was actually mandatory.
Related errors
- ErrorSecNoSuchKeychain
- ErrorSecInvalidKeychain
- ErrorSecAuthFailed
- ErrorSecDuplicateItem
- ErrorSecItemNotFound
AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11).
Data as JSON: /api/errors/a08a9ceb5a0fb3f6.
Report an issue: GitHub.
Appendix: source
Thrown at src/Core/Interop/MacOS/Native/SecurityFramework.cs:154
{
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);
}
}
}
[Flags]
public enum SessionAttributeBits
{
SessionIsRoot = 0x0001,
SessionHasGraphicAccess = 0x0010,
SessionHasTty = 0x0020,
SessionIsRemote = 0x1000,
}
[StructLayout(LayoutKind.Sequential)]View on GitHub (pinned to e8ce762cd0)