When This Error Shows Up
You're running SQL Server Management Studio, and suddenly queries hang. Or you're using Docker Desktop, and containers won't start. Or maybe you wrote a custom service that communicates with a client over named pipes. The error code 0XC00000B1 pops up, and the message says: "The specified named pipe is in the closing state."
I've seen this most often in three scenarios: (1) A SQL Server instance that's being restarted while clients are still connected. (2) A Docker daemon that's recycling after a configuration change. (3) Custom .NET applications that call CreateNamedPipe or WaitNamedPipe but don't handle disconnects properly.
What's Actually Happening
Named pipes are like phone lines between two programs. One program (the server) creates the pipe and waits for calls. Another program (the client) connects and sends data. When the pipe is closing, it means the server has hung up, but the client is still trying to talk. The client gets STATUS_PIPE_CLOSING (error code 0XC00000B1) because the pipe handle is being torn down.
This isn't a "broken" pipe — that's a different error. This is a pipe that's in the process of closing. The server called DisconnectNamedPipe or CloseHandle, but the client hasn't gotten the memo yet. Sometimes it's a race condition: the client sends data at the exact moment the server decides to close. Other times, it's a resource leak where hundreds of stale pipes pile up.
The root cause? Either the server shut down unexpectedly (crash, restart, or manual stop) while clients were connected, or the client code doesn't retry after receiving this error. In SQL Server, this happens when you restart the SQL Browser service or the named pipes protocol is disabled/enabled mid-session. In Docker, it's often the Docker engine restarting or a DNS resolution timeout.
How to Fix It
Skip the generic "restart your computer" advice. That's a sledgehammer when you need a scalpel. Here's the real fix, step by step.
Step 1: Identify the Pipe in Question
Open an elevated Command Prompt (Run as Administrator) and run:
powershell Get-ChildItem -Path \\.\\pipe\\This lists all active named pipes. Look for pipes with names like SqlQueryPipe, docker-engine, or your custom app's pipe. If the pipe is missing, the server already shut down. If it's present, check if the server process is still running.
To find which process owns a pipe, use Sysinternals' Handle tool:
handle -a -p <processname>Look for handles of type File with names containing \\.\\pipe\\.
Step 2: Restart the Server Process Properly
If this is SQL Server, go to SQL Server Configuration Manager, right-click SQL Server Browser, and select Restart. Then restart SQL Server (MSSQLSERVER) service. This forces a clean creation of all named pipes.
For Docker Desktop, open Settings, go to Troubleshoot, and click "Reset to factory defaults". Don't just restart the app — that doesn't clear stale pipe handles.
For custom apps, stop the server process gracefully (send a shutdown signal, not a kill), then start it again. Avoid taskkill /f unless absoltely necessary — it doesn't let the server clean up pipes.
Step 3: Update Your Client Code to Retry
If you're writing your own client, this error is a signal to retry. Here's a C# snippet that handles it:
using (var pipe = new NamedPipeClientStream(".", "pipename", PipeDirection.InOut))
{
int retries = 0;
while (retries < 3)
{
try
{
pipe.Connect(5000);
break;
}
catch (TimeoutException)
{
retries++;
Thread.Sleep(1000);
}
}
}
The key is to catch IOException with the HResult 0x800700B1 and retry after a short pause (1-2 seconds). Don't retry immediately — you'll just hammer the server.
Step 4: Check for Handle Leaks
Open Resource Monitor (resmon.exe), go to the Handles tab, and filter by "Pipe". If you see hundreds of pipe handles from one process, that's your problem. The server isn't closing pipes when clients disconnect. This is common in poorly written service apps that create new pipes for each client but never call DisconnectNamedPipe or CloseHandle.
Fix: In your server code, ensure every CreateNamedPipe has a matching CloseHandle in the cleanup path. Use using blocks in C# or RAII in C++.
What to Check If It Still Fails
If none of those steps help, there are two less common culprits.
First, antivirus software. Some security tools intercept pipe operations and hold them open. Temporarily disable real-time protection and test. If the error stops, add an exception for your process.
Second, Windows Firewall. Named pipes that use TCP/IP (like SQL Server's named pipes) can be blocked by firewall rules. Check Windows Defender Firewall with Advanced Security — look for inbound rules blocking SQL Server or Docker.
Last resort: Run netstat -anb in an elevated command prompt and look for LISTENING state on port 445. If that port is in use by another program, pipe communication fails entirely.
This error is annoying, but it's not a system failure. It's a timing problem or a cleanup gap. Track down the pipe, restart the server cleanly, and update your client to retry. That trio of fixes handles 95% of cases.