git-ecosystem/git-credential-manager · error · IOException
Failed to enter raw console mode on
Error message
Failed to enter raw console mode on {ConsoleInName}. What it means
EnterRawMode strips LineInput, EchoInput, and ProcessedInput from the saved console mode via Kernel32.SetConsoleMode so keystrokes (Ctrl+C, arrows) reach GCM unprocessed. If SetConsoleMode fails, it throws IOException because raw-mode reads cannot be performed reliably on the handle.
Solutions
- Retry the credential prompt in a standard console (Windows Terminal or conhost).
- Avoid wrapper layers that proxy console handles; run git directly or use winpty.
- Fall back to non-raw authentication: GCM_INTERACTIVE=never plus a pre-provisioned credential store.
- If reproducible, check Windows/console-emulator version and update the terminal emulator.
Example fix
// before // IDE embedded terminal intercepting CONIN$ // after // run from Windows Terminal, or: set GCM_INTERACTIVE=never
Defensive patterns
Strategy: try-catch
Validate before calling
if (!Kernel32.GetConsoleMode(h, out var m)) return false; // can't even read mode if ((m & (ConsoleMode.LineInput | ConsoleMode.EchoInput)) == 0) return false;
Type guard
static bool SupportsRawMode(SafeFileHandle h) =>
Kernel32.GetConsoleMode(h, out var mode) &&
Kernel32.SetConsoleMode(h, mode) && Kernel32.SetConsoleMode(h, mode); Try / catch
try { input.AcquireRawMode(); ... }
catch (IOException ex) when (ex.Message.Contains("raw console mode"))
{ logger.Warn("Raw mode unavailable; using line-based input or fallback store."); } Prevention
- Avoid IDE-embedded or ConPTY wrappers known to reject SetConsoleMode; test in Windows Terminal.
- Keep the input handle exclusively owned by the reader thread.
- Provide a line-based prompt fallback when raw mode fails.
- Update terminal emulator if raw-mode failures are reproducible.
When it happens
Trigger: Calling AcquireRawMode (during a keystroke read) when SetConsoleMode on the CONIN$ handle returns false — the handle lost console status, was closed by another thread, or the console host rejected the mode change.
Common situations: Terminal host (ConPTY-based emulators, some IDE terminals) rejecting mode changes; the input handle invalidated between open and raw-mode entry; running under process wrappers that intercept console APIs; rare Windows console substitution.
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
- Failed to open for reading.
- Failed to read initial console mode on
- Failed to open for writing.
- Failed to read initial terminal settings.
- Failed to enter raw terminal mode.
AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11).
Data as JSON: /api/errors/213f00e68157e19a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Core/Interop/Windows/WindowsAnsiConsoleInput.cs:105
// The console is left in its normal (cooked) mode except during an
// active keystroke read (see ReadKey). That is what keeps Ctrl+C working
// when GCM is doing other work — MSAL polling, a GUI, the network — and
// not just while a Spectre prompt happens to be reading: with
// ProcessedInput on, Ctrl+C raises CTRL_C_EVENT and the runtime's
// default handler terminates the process.
}
// Switch the console into raw mode (no echo, no line input, no system Ctrl+C
// handling) for the duration of a read. Caller must hold _modeLock.
private void EnterRawMode()
{
ConsoleMode rawMode = _originalMode
& ~(ConsoleMode.LineInput | ConsoleMode.EchoInput | ConsoleMode.ProcessedInput);
if (!Kernel32.SetConsoleMode(_handle, rawMode))
{
throw new IOException($"Failed to enter raw console mode on {ConsoleInName}.");
}
_inRawMode = true;
}
// Restore the original (cooked) console mode after a read. Idempotent.
// Caller must hold _modeLock.
private void RestoreMode()
{
if (!_inRawMode)
{
return;
}
if (!_handle.IsInvalid && !_handle.IsClosed)
{
Kernel32.SetConsoleMode(_handle, _originalMode);
}View on GitHub (pinned to e8ce762cd0)