micro/go-micro · info
connection header set to close
Error message
connection header set to close
What it means
In client/rpc_stream.go:180, rpcStream.Close closes the codec and then checks r.Error(); if the stream was marked with r.close and no other error occurred, it synthesizes errors.New("connection header set to close") as the stream error before releasing the connection. This signals that the connection was intentionally torn down because the close flag was set (the underlying transport/connection header requested closure).
Source
Thrown at client/rpc_stream.go:180
// send the end of stream message
if r.sendEOS {
// no need to check for error
//nolint:errcheck,gosec
r.codec.Write(&codec.Message{
Id: r.id,
Target: r.request.Service(),
Method: r.request.Method(),
Endpoint: r.request.Endpoint(),
Type: codec.Error,
Error: lastStreamResponseError,
}, nil)
}
err := r.codec.Close()
rerr := r.Error()
if r.close && rerr == nil {
rerr = errors.New("connection header set to close")
}
// release the connection
r.release(rerr)
return err
}
}
View on GitHub (pinned to 24529f1404)
Solutions
- Ignore this error when it indicates an expected connection teardown (compare against the message or just log at debug level)
- Check r.Error() before Close to distinguish real stream errors from the teardown sentinel
- Ensure connection pooling re-establishes connections rather than treating this as fatal
Example fix
// before
if err := stream.Close(); err != nil { return err }
// after
if err := stream.Close(); err != nil && !strings.Contains(err.Error(), "connection header set to close") {
return err
} Defensive patterns
Strategy: type-guard
Validate before calling
// optional: inspect stream error before closing to separate real faults serr := stream.Error() // if non-nil, real failure; Close()'s sentinel is noise
Type guard
func isConnCloseTeardown(err error) bool {
return err != nil && strings.Contains(err.Error(), "connection header set to close")
} Try / catch
if err := stream.Close(); err != nil && !isConnCloseTeardown(err) {
return fmt.Errorf("stream close failed: %w", err)
}
// teardown sentinel ignored Prevention
- Treat this error as informational connection teardown, not a fault
- Ensure your connection pool handles non-reusable connections
- Log real stream errors (stream.Error()) separately from close-time sentinels
When it happens
Trigger: Closing a stream when r.close is true — i.e. the transport indicated the connection should be closed (connection: close semantics) — while the codec itself closed without error.
Common situations: HTTP/1.1 connections with connection: close being recycled; server asking clients not to reuse connections; pool eviction on stream teardown.
Related errors
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/9e1454d67506c478.
Report an issue: GitHub.