cloudflare/cloudflared · error
not a tcp connection
Error message
not a tcp connection
What it means
ConnDialer.Dial inspects the underlying connection's LocalAddr and requires it to be a *net.TCPAddr to construct the AddrSpec reported to the SOCKS client. If the wrapped conn is not a TCP connection (e.g. Unix socket), Dial returns 'not a tcp connection'.
Source
Thrown at socks/dialer.go:52
}
// ConnDialer is like NetDialer but with an existing TCP dialer already created
type ConnDialer struct {
conn net.Conn
}
// NewConnDialer creates a new dialer with a already created net.conn (TCP expected)
func NewConnDialer(conn net.Conn) Dialer {
return &ConnDialer{
conn: conn,
}
}
// Dial is a TCP dialer but already created
func (d *ConnDialer) Dial(address string) (io.ReadWriteCloser, *AddrSpec, error) {
local, ok := d.conn.LocalAddr().(*net.TCPAddr)
if !ok {
return nil, nil, fmt.Errorf("not a tcp connection")
}
addr := AddrSpec{IP: local.IP, Port: local.Port}
return d.conn, &addr, nil
}
View on GitHub (pinned to 2253eeeb25)
Solutions
- Serve the SOCKS handler on a TCP listener so conn.LocalAddr() is *net.TCPAddr.
- Remove the Unix socket/pipe wrapper for this handler.
- If a non-TCP transport is required, supply a dialer that can produce an AddrSpec without a TCP local address.
- Check how the conn passed into ConnDialer is created.
Example fix
// before
ln, _ := net.Listen("unix", "/tmp/socks.sock")
// after
ln, _ := net.Listen("tcp", "127.0.0.1:1080") Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := conn.LocalAddr().(*net.TCPAddr); !ok { return errors.New("socks handler requires TCP connection") } Type guard
func isTCPConn(conn net.Conn) bool { _, ok := conn.LocalAddr().(*net.TCPAddr); return ok } Try / catch
rwc, addr, err := dialer.Dial(address)
if err != nil {
return fmt.Errorf("cannot determine local addr: %w", err)
} Prevention
- Serve SOCKS on a TCP listener only
- Avoid wrapping the handler behind Unix sockets/net.Pipe
- Use a custom dialer for non-TCP transports
- Assert conn type in tests
When it happens
Trigger: Serving the SOCKS handler over a listener whose accepted connections are not *net.TCPConn, then a client requests a BIND-style reply needing the local address.
Common situations: Wrapping the SOCKS handler behind a Unix socket or in-memory pipe; test harnesses using net.Pipe; unusual listener configurations.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Connect to %v failed: %v
- cloudflared received a warp-routing request with an empty ho
- unable to dial tcp to origin %s: %w
- Failed to read auth methods: %v
- unknown authentication type
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/c8fae7733710d120.
Report an issue: GitHub.