git-ecosystem/git-credential-manager · error · IOException
Failed to read initial console mode on
Error message
Failed to read initial console mode on {ConsoleInName}. What it means
After opening CONIN$, WindowsAnsiConsoleInput calls Kernel32.GetConsoleMode to capture the original (cooked) console mode so it can be restored later. If GetConsoleMode fails, the handle does not refer to a console, so the constructor throws IOException to avoid entering/exiting raw mode on a non-console device.
Solutions
- Run git with a genuine console stdin (don't redirect stdin when interactive auth may occur).
- Under mintty/MSYS shells, use winpty (winpty git push) so a real Windows console is provided.
- Set GCM_INTERACTIVE=never or pre-provision credentials (wincredman store, PAT in config) so no console input is attempted.
- Pre-cache credentials with an interactive run once, then use non-interactive runs in scripts/pipes.
Example fix
// before type input.txt | git push // stdin is a pipe -> GetConsoleMode fails // after winpty git push # or: git config credential.credentialStore wincredman
Defensive patterns
Strategy: validation
Validate before calling
if (!Kernel32.GetConsoleMode(consoleIn, out _))
throw new InvalidOperationException("stdin is not a real console; interactive prompt unavailable."); Type guard
static bool IsConsoleInput(IntPtr handle) =>
Kernel32.GetConsoleMode(handle, out _); // pipes/files have no console mode Try / catch
try { using var input = new WindowsAnsiConsoleInput(); ... }
catch (IOException ex) when (ex.Message.Contains("initial console mode"))
{ // stdin redirected: fall back to winpty or non-interactive store
return NonInteractiveFallback(); } Prevention
- Avoid piping/redirecting stdin into git commands that may prompt for credentials.
- Under mintty/MSYS, prefix with winpty to get a real console.
- Pre-cache credentials so prompts never occur in scripts.
- Set GCM_INTERACTIVE=never in automation.
When it happens
Trigger: The CONIN$ handle opened successfully but GetConsoleMode returned false — input is redirected to a file/pipe rather than an actual console buffer, or the handle was closed concurrently.
Common situations: Running git with stdin redirected from a file or pipe (e.g. `git fetch < input.txt`, piping into git) while GCM tries to prompt for input; running under wrappers that fake console handles; unusual terminal emulators (e.g. mintty without winpty) providing pipes instead of console handles.
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
- Failed to open for reading.
- Failed to enter raw console mode on
- Failed to open for writing.
- Failed to enter raw terminal mode.
- Unable to persist credentials with the
AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11).
Data as JSON: /api/errors/fe6fb5d0b46f9ad6.
Report an issue: GitHub.
Appendix: source
Thrown at src/Core/Interop/Windows/WindowsAnsiConsoleInput.cs:85
_handle = Kernel32.CreateFile(
fileName: ConsoleInName,
desiredAccess: NativeFileAccess.GenericRead | NativeFileAccess.GenericWrite,
shareMode: NativeFileShare.Read | NativeFileShare.Write,
securityAttributes: IntPtr.Zero,
creationDisposition: FileCreationDisposition.OpenExisting,
flagsAndAttributes: NativeFileAttributes.Normal,
templateFile: IntPtr.Zero);
if (_handle.IsInvalid)
{
_handle.Dispose();
throw new IOException($"Failed to open {ConsoleInName} for reading.");
}
if (!Kernel32.GetConsoleMode(_handle, out _originalMode))
{
_handle.Dispose();
throw new IOException($"Failed to read initial console mode on {ConsoleInName}.");
}
// 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))View on GitHub (pinned to e8ce762cd0)