valyala/fasthttp · error
dialling unsuccessful: please report this bug
Error message
dialling unsuccessful: please report this bug
What it means
This error is returned when the configured dial function returns both a nil error and a nil connection — an impossible result indicating a bug. fasthttp treats it as a programming error in the DialFunc and asks for a bug report.
Source
Thrown at client.go:2332
}
err = conn.SetDeadline(time.Time{})
if err != nil {
return nil, err
}
return conn, nil
}
func dialAddr(
addr string, dial DialFunc, dialWithTimeout DialFuncWithTimeout, dialDualStack, isTLS bool,
tlsConfig *tls.Config, dialTimeout, writeTimeout time.Duration,
) (net.Conn, error) {
deadline := time.Now().Add(writeTimeout)
conn, err := callDialFunc(addr, dial, dialWithTimeout, dialDualStack, isTLS, dialTimeout)
if err != nil {
return nil, err
}
if conn == nil {
return nil, errors.New("dialling unsuccessful: please report this bug")
}
// We assume that any conn that has the Handshake() method is a TLS conn already.
// This doesn't cover just tls.Conn but also other TLS implementations.
_, isTLSAlready := conn.(interface{ Handshake() error })
if isTLS && !isTLSAlready {
if writeTimeout == 0 {
return tls.Client(conn, tlsConfig), nil
}
return tlsClientHandshake(conn, tlsConfig, deadline)
}
return conn, nil
}
func callDialFunc(
addr string, dial DialFunc, dialWithTimeout DialFuncWithTimeout, dialDualStack, isTLS bool, timeout time.Duration,
) (net.Conn, error) {View on GitHub (pinned to c96f600972)
Solutions
- Fix the custom DialFunc so every path returns either a non-nil conn or a non-nil error
- Audit wrapped/proxied dialers for paths that return nil, nil (often after type assertions)
- If using the library's default dial chain with no custom dials, report the bug to fasthttp with a reproducer
- Add a defensive assertion/log at the dialer boundary to catch nil, nil during development
Example fix
// before (buggy custom dialer)
func dial(addr string) (net.Conn, error) {
c, err := net.Dial("tcp", addr)
if err != nil { return nil, err }
if bad(c) { return } // returns nil, nil!
return c, nil
}
// after
func dial(addr string) (net.Conn, error) {
c, err := net.Dial("tcp", addr)
if err != nil { return nil, err }
if bad(c) { return nil, errors.New("dial: unusable conn") }
return c, nil
} Defensive patterns
Strategy: validation
Validate before calling
conn, err := dialFn(addr)
if err == nil && conn == nil {
return nil, errors.New("dialer bug: returned nil conn with nil error")
} Type guard
func validDialResult(c net.Conn, err error) bool {
return (err == nil) == (c != nil)
} Try / catch
if err != nil && strings.Contains(err.Error(), "dialling unsuccessful") {
// do not retry; fix the DialFunc
} Prevention
- Wrap custom dialers with a nil, nil assertion in tests
- Ensure every branch of DialFunc returns a conn or an error
- Unit-test wrapped dialers on failure paths
- Report library-internal occurrences upstream with a reproducer
When it happens
Trigger: A custom Client.Dial / DialFunc (or the dial, dialWithTimeout, dialDualStack wrapper chain in callDialFunc) returns (nil, nil) instead of either a valid net.Conn or a non-nil error.
Common situations: Custom dialers with code paths that forget to return the connection (e.g. early return after a failed cast); buggy wrapped or third-party dial implementations.
Related errors
- fasthttp: missing location header for http redirect
- fasthttp: too many redirects detected when doing the request
- fasthttp: hostclient can't follow redirects to a different p
- fasthttp: no free connections available to host
- fasthttp: the server closed connection before returning the
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/487ab64612286ad0.
Report an issue: GitHub.