{"record":{"id":"487ab64612286ad0","repo":"valyala/fasthttp","slug":"dialling-unsuccessful-please-report-this-bug","errorCode":null,"errorMessage":"dialling unsuccessful: please report this bug","messagePattern":"dialling unsuccessful: please report this bug","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client.go","lineNumber":2332,"sourceCode":"\t}\n\terr = conn.SetDeadline(time.Time{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn conn, nil\n}\n\nfunc dialAddr(\n\taddr string, dial DialFunc, dialWithTimeout DialFuncWithTimeout, dialDualStack, isTLS bool,\n\ttlsConfig *tls.Config, dialTimeout, writeTimeout time.Duration,\n) (net.Conn, error) {\n\tdeadline := time.Now().Add(writeTimeout)\n\tconn, err := callDialFunc(addr, dial, dialWithTimeout, dialDualStack, isTLS, dialTimeout)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif conn == nil {\n\t\treturn nil, errors.New(\"dialling unsuccessful: please report this bug\")\n\t}\n\n\t// We assume that any conn that has the Handshake() method is a TLS conn already.\n\t// This doesn't cover just tls.Conn but also other TLS implementations.\n\t_, isTLSAlready := conn.(interface{ Handshake() error })\n\n\tif isTLS && !isTLSAlready {\n\t\tif writeTimeout == 0 {\n\t\t\treturn tls.Client(conn, tlsConfig), nil\n\t\t}\n\t\treturn tlsClientHandshake(conn, tlsConfig, deadline)\n\t}\n\treturn conn, nil\n}\n\nfunc callDialFunc(\n\taddr string, dial DialFunc, dialWithTimeout DialFuncWithTimeout, dialDualStack, isTLS bool, timeout time.Duration,\n) (net.Conn, error) {","sourceCodeStart":2314,"sourceCodeEnd":2350,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/client.go#L2314-L2350","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (buggy custom dialer)\nfunc dial(addr string) (net.Conn, error) {\n    c, err := net.Dial(\"tcp\", addr)\n    if err != nil { return nil, err }\n    if bad(c) { return } // returns nil, nil!\n    return c, nil\n}\n// after\nfunc dial(addr string) (net.Conn, error) {\n    c, err := net.Dial(\"tcp\", addr)\n    if err != nil { return nil, err }\n    if bad(c) { return nil, errors.New(\"dial: unusable conn\") }\n    return c, nil\n}","handlingStrategy":"validation","validationCode":"conn, err := dialFn(addr)\nif err == nil && conn == nil {\n    return nil, errors.New(\"dialer bug: returned nil conn with nil error\")\n}","typeGuard":"func validDialResult(c net.Conn, err error) bool {\n    return (err == nil) == (c != nil)\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"dialling unsuccessful\") {\n    // do not retry; fix the DialFunc\n}","preventionTips":["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"],"tags":["dial","bug","client","programming-error"],"backgroundTag":"custom-dial-func-bug","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}