docker/cli · error
the raw stream connection does not implement halfCloser
Error message
the raw stream connection does not implement halfCloser
What it means
Raised by `docker system dial-stdio` when the connection returned by the API client's Dialer does not support half-close semantics (CloseRead/CloseWrite) and is not even a half-read/write-closer the CLI can wrap. dial-stdio proxies stdin/stdout to the raw Docker daemon stream and needs to close each direction independently, so a connection type without those methods cannot be used.
Source
Thrown at cli/command/system/dial_stdio.go:50
func runDialStdio(ctx context.Context, dockerCli command.Cli) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
dialer := dockerCli.Client().Dialer()
conn, err := dialer(ctx)
if err != nil {
return fmt.Errorf("failed to open the raw stream connection: %w", err)
}
defer conn.Close()
var connHalfCloser halfCloser
switch t := conn.(type) {
case halfCloser:
connHalfCloser = t
case halfReadWriteCloser:
connHalfCloser = &nopCloseReader{t}
default:
return errors.New("the raw stream connection does not implement halfCloser")
}
stdin2conn := make(chan error, 1)
conn2stdout := make(chan error, 1)
go func() {
stdin2conn <- copier(connHalfCloser, &halfReadCloserWrapper{os.Stdin}, "stdin to stream")
}()
go func() {
conn2stdout <- copier(&halfWriteCloserWrapper{os.Stdout}, connHalfCloser, "stream to stdout")
}()
select {
case err = <-stdin2conn:
if err != nil {
return err
}
// wait for stdout
err = <-conn2stdout
case err = <-conn2stdout:View on GitHub (pinned to e9452d6e78)
Solutions
- Connect over a transport that supports half-close: unix socket (unix:///var/run/docker.sock) or plain tcp:// instead of a wrapped/proxied transport.
- If using ssh:// or a connection helper, update the docker CLI — half-close handling for wrapped connections has improved across versions.
- As a workaround, avoid dial-stdio by pointing the client directly at the daemon endpoint (set DOCKER_HOST) rather than tunneling through the CLI.
When it happens
Trigger: Running `docker system dial-stdio` when dockerCli.Client().Dialer() yields a net.Conn type that implements neither the halfCloser interface (CloseRead+CloseWrite) nor halfReadWriteCloser — e.g. certain tunneled, proxied, or custom transport connections (some TLS or exotic connection helpers) instead of a plain *net.TCPConn or *net.UnixConn.
Common situations: Using dial-stdio (often invoked implicitly by `docker -H ssh://...` or buildx/BuildKit clients) through a connection helper or proxy whose transport doesn't expose half-close; custom DOCKER_HOST transports; older/newer client-transport combinations changing the concrete conn type.
Related errors
- failed to parse hook template
- unexpected hook response type:
- plugin candidate path cannot be empty
- plugin SchemaVersion version cannot be empty
- plugin server is closed
AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01).
Data as JSON: /data/errors/e9c24dd826e2a64d.json.
Report an issue: GitHub.