felixse/FluentTerminal · critical · Win32Exception

failed to create pipe

Error message

failed to create pipe

What it means

Thrown by PseudoConsolePipe's constructor when the Win32 CreatePipe P/Invoke returns false. The ConPty backend creates an anonymous pipe (one read handle, one write handle) to feed input to and drain output from the pseudoconsole; if the kernel cannot create the pipe, GetLastWin32Error is wrapped in a Win32Exception with this message.

Source

Thrown at FluentTerminal.SystemTray/Services/ConPty/PseudoConsolePipe.cs:25

namespace FluentTerminal.SystemTray.Services.ConPty
{
    /// <summary>
    /// A pipe used to talk to the pseudoconsole, as described in:
    /// https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session
    /// </summary>
    /// <remarks>
    /// We'll have two instances of this class, one for input and one for output.
    /// </remarks>
    internal sealed class PseudoConsolePipe : IDisposable
    {
        public readonly SafeFileHandle ReadSide;
        public readonly SafeFileHandle WriteSide;

        public PseudoConsolePipe()
        {
            if (!CreatePipe(out ReadSide, out WriteSide, IntPtr.Zero, 0))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(), "failed to create pipe");
            }
        }

        ~PseudoConsolePipe()
        {
            Dispose(false);
        }

        #region IDisposable

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        void Dispose(bool disposing)
        {

View on GitHub (pinned to ba83ec485e)

Solutions

  1. Ensure the app disposes Terminal/PseudoConsolePipe instances promptly to avoid handle leaks.
  2. Run on Windows 10 1809 (build 17763) or later where the ConPty API is available.
  3. Inspect the Win32Exception.NativeErrorCode (e.g. ERROR_TOO_MANY_OPEN_FILES) to pinpoint resource exhaustion.
  4. Restart the app/session to release leaked handles.

Example fix

// before
if (!CreatePipe(out ReadSide, out WriteSide, IntPtr.Zero, 0))
    throw new Win32Exception(Marshal.GetLastWin32Error(), "failed to create pipe");

// after - include the native error code in the message for diagnostics
int err = Marshal.GetLastWin32Error();
throw new Win32Exception(err, $"failed to create pipe (Win32 error {err})");
Defensive patterns

Strategy: try-catch

Validate before calling

// No cheap pre-check; ensure handles are disposed to avoid exhaustion.
// Monitor handle count before creating a terminal:
using (var proc = Process.GetCurrentProcess())
    if (proc.HandleCount > 9000) logger.Warn("Handle count high; ConPty pipe creation may fail.");

Try / catch

try { terminal = new Terminal(); /* pipes created in Start */ }
catch (System.ComponentModel.Win32Exception ex) { logger.Error(ex, $"pipe create failed (Win32 {ex.NativeErrorCode})"); fallbackToWinPty(); }

Prevention

When it happens

Trigger: Constructing a PseudoConsolePipe (two are made per Terminal.Start: input and output) on a system where CreatePipe fails - typically due to handle exhaustion or resource limits, not normal usage.

Common situations: Process has leaked handles and hit the 10k-default handle quota; running under a heavily constrained session/job object; rare kernel/resource pressure. ConPty itself requires Windows 10 1809+.

Related errors


AI-assisted analysis of felixse/FluentTerminal@ba83ec485e (2026-08-13). Data as JSON: /api/errors/bbce27c927734bdf. Report an issue: GitHub.