git-ecosystem/git-credential-manager · error · IOException

Failed to open for reading.

Error message

Failed to open {ConsoleInName} for reading.

What it means

WindowsAnsiConsoleInput's constructor opens the console input device (CONIN$) via CreateFile to read keystrokes, then reads the initial console mode. If the returned handle is invalid it disposes it and throws IOException, failing fast instead of reading from a broken handle.

Solutions

  1. Run git from a real console (Windows Terminal, conhost) so CONIN$ is available.
  2. Use a non-interactive configuration: set GCM_INTERACTIVE=never or choose the Windows credential store (credential.credentialStore=wincredman) so no console input is required.
  3. If launching from a GUI/scheduler, attach or allocate a console (AttachConsole/AllocConsole) or avoid interactive auth by pre-caching credentials.
  4. Check that the host application isn't stripping standard handles before spawning git.

Example fix

// before (scheduled task, no console)
schtasks /run /tn gitbackup   // IOException: failed to open CONIN$
// after
schtasks options -> run only when user is logged on, or set:
set GCM_INTERACTIVE=never && git config credential.credentialStore wincredman
Defensive patterns

Strategy: fallback

Validate before calling

var h = Kernel32.CreateFile("CONIN$", ..., ...);
bool usable = !h.IsInvalid && Kernel32.GetConsoleMode(h, out _);

Type guard

static bool HasConsole() =>
    Kernel32.GetConsoleWindow() != IntPtr.Zero &&
    Kernel32.GetConsoleMode(Kernel32.CreateFile("CONIN$", 0x80000000, 0, IntPtr.Zero, 3, 0, IntPtr.Zero), out _);

Try / catch

try { using var input = new WindowsAnsiConsoleInput(); ... }
catch (IOException)
{ // no console: switch to non-interactive credential store
  cred = winCredManStore.Get(target); }

Prevention

When it happens

Trigger: Creating WindowsAnsiConsoleInput when CreateFile on CONIN$ fails: no console attached to the process (windows/gui subsystem app, detached service, redirected standard handles without a console).

Common situations: git invoked from a GUI launcher or scheduled task with no console; running under a service account with no interactive session; a terminal whose input handle was closed or redirected (e.g. `git push < NUL` in some hosts).

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


AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11). Data as JSON: /api/errors/3ae5518c8c03bbf2. Report an issue: GitHub.

Appendix: source

Thrown at src/Core/Interop/Windows/WindowsAnsiConsoleInput.cs:79

    private int _rawDepth;

    public WindowsAnsiConsoleInput()
    {
        PlatformUtils.EnsureWindows();

        _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.

View on GitHub (pinned to e8ce762cd0)