{"record":{"id":"d6190f4b9f745cf2","repo":"nats-io/nats-server","slug":"failed-to-set-deadline-v","errorCode":null,"errorMessage":"failed to set deadline: %v","messagePattern":"failed to set deadline: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/leafnode.go","lineNumber":638,"sourceCode":"\n// establishHTTPProxyTunnel establishes an HTTP CONNECT tunnel through a proxy server\nfunc establishHTTPProxyTunnel(proxyURL, targetHost string, timeout time.Duration, username, password string) (net.Conn, error) {\n\tproxyAddr, err := url.Parse(proxyURL)\n\tif err != nil {\n\t\t// This should not happen since proxy URL is validated during configuration parsing\n\t\treturn nil, fmt.Errorf(\"unexpected proxy URL parse error (URL was pre-validated): %v\", err)\n\t}\n\n\t// Connect to the proxy server\n\tconn, err := natsDialTimeout(\"tcp\", proxyAddr.Host, timeout)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to connect to proxy: %v\", err)\n\t}\n\n\t// Set deadline for the entire proxy handshake\n\tif err := conn.SetDeadline(time.Now().Add(timeout)); err != nil {\n\t\tconn.Close()\n\t\treturn nil, fmt.Errorf(\"failed to set deadline: %v\", err)\n\t}\n\n\treq := &http.Request{\n\t\tMethod: http.MethodConnect,\n\t\tURL:    &url.URL{Opaque: targetHost}, // Opaque is required for CONNECT\n\t\tHost:   targetHost,\n\t\tHeader: make(http.Header),\n\t}\n\n\t// Add proxy authentication if provided\n\tif username != \"\" && password != \"\" {\n\t\treq.Header.Set(\"Proxy-Authorization\", \"Basic \"+base64.StdEncoding.EncodeToString([]byte(username+\":\"+password)))\n\t}\n\n\tif err := req.Write(conn); err != nil {\n\t\tconn.Close()\n\t\treturn nil, fmt.Errorf(\"failed to write CONNECT request: %v\", err)\n\t}","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/leafnode.go#L620-L656","documentation":"Setting the handshake deadline on the freshly opened proxy connection failed. The code calls conn.SetDeadline(time.Now().Add(timeout)) to bound the entire CONNECT exchange; a non-nil error (e.g. the conn is already closed or the underlying transport does not support deadlines) aborts the tunnel. This is rare and usually indicates a broken/aborted connection immediately after dial.","triggerScenarios":"conn.SetDeadline returning an error right after natsDialTimeout succeeded — connection reset/closed between dial and deadline set, or a custom net.Conn implementation without deadline support injected in tests.","commonSituations":"Proxy closing the socket instantly (port opened then dropped by an LB or tcpwrap); test doubles using pipe connections without deadline support; kernel-level connection aborts under load.","solutions":["Retry the connection — the socket was likely reset by the peer","Inspect why the proxy/LB drops connections right after accept","In tests, use deadline-capable pipes (net.Pipe wrapped) or a real listener"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"conn, err := establishHTTPProxyTunnel(purl, target, timeout, user, pass)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to set deadline\") {\n        time.Sleep(backoff)\n        conn, err = establishHTTPProxyTunnel(purl, target, timeout, user, pass)\n    }\n    if err != nil { return err }\n}","preventionTips":["Retry transient socket resets with backoff","Investigate LB/tcwrap rules that accept then drop connections","In tests use deadline-capable transports"],"tags":["network","proxy","timeout","connection"],"backgroundTag":"connection-reset","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}