{"record":{"id":"5b585b6cb4c47e31","repo":"owasp-amass/amass","slug":"failed-to-send-the-request-to-the-whois-server-v","errorCode":null,"errorMessage":"failed to send the request to the WHOIS server: %v","messagePattern":"failed to send the request to the WHOIS server: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/plugins/whois/bgptools/plugin.go","lineNumber":147,"sourceCode":"}\n\nfunc (bt *bgpTools) whois(ctx context.Context, ipstr string) (*bgpToolsRecord, error) {\n\tdial := amassnet.NewDialContext(3 * time.Second)\n\taddr := net.JoinHostPort(bt.addr, strconv.Itoa(bt.port))\n\n\t_ = bt.rlimit.Wait(ctx)\n\tctx, cancel := context.WithTimeout(ctx, 10*time.Second)\n\tdefer cancel()\n\n\tconn, err := dial(ctx, \"tcp\", addr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to establish a connection with the WHOIS server: %v\", err)\n\t}\n\tdefer func() { _ = conn.Close() }()\n\n\tn, err := io.WriteString(conn, fmt.Sprintf(\"begin\\n%s\\nend\", ipstr))\n\tif err != nil || n == 0 {\n\t\treturn nil, fmt.Errorf(\"failed to send the request to the WHOIS server: %v\", err)\n\t}\n\n\tdata, err := io.ReadAll(conn)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error reading the response from the WHOIS server: %v\", err)\n\t}\n\n\trecord := strings.Split(string(data), \"|\")\n\t// Ensure the record contains the necessary details (AutonomousSystem and Netblock)\n\tif len(record) < 7 {\n\t\treturn nil, errors.New(\"received insufficient data from the WHOIS server\")\n\t}\n\n\tvar r bgpToolsRecord\n\tfor i, f := range record {\n\t\tfield := strings.TrimSpace(f)\n\n\t\tswitch i {","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/engine/plugins/whois/bgptools/plugin.go#L129-L165","documentation":"The bgptools WHOIS plugin wraps write errors when sending the `begin\\n<ip>\\nend` request over the established TCP connection. io.WriteString returning an error or zero bytes written means the request never reached the server, usually because the connection was closed or reset by the peer mid-request.","triggerScenarios":"Calling whois(ctx, ipstr) where the TCP connection succeeds but io.WriteString(conn, \"begin\\n%s\\nend\") fails (err != nil) or writes 0 bytes — typically a broken pipe/reset, connection closed by server, or timeout firing mid-write.","commonSituations":"Server closed the connection immediately after accept (rate limiting/banning by bgp.tools); the 10s deadline expired during the write; a NAT/firewall dropped an idle-looking connection; the IP string argument was empty causing an immediate server-side close.","solutions":["Inspect the wrapped cause (`%v`) — ECONNRESET/broken pipe usually means server-side close or rate limiting","Check whether the IP string passed in is a valid, non-empty IP before calling","Verify the 10s timeout is adequate for the network path; increase the deadline if writes are timing out","Reduce request rate / honor bgp.tools rate limits to avoid being disconnected","Retry the query with backoff; transient resets often succeed on a fresh connection"],"exampleFix":"// before\nn, err := io.WriteString(conn, fmt.Sprintf(\"begin\\n%s\\nend\", ipstr))\n// after\nif net.ParseIP(ipstr) == nil {\n    return nil, fmt.Errorf(\"invalid IP argument: %q\", ipstr)\n}\nconn.SetDeadline(time.Now().Add(10 * time.Second))\nn, err := io.WriteString(conn, fmt.Sprintf(\"begin\\n%s\\nend\\n\", ipstr))","handlingStrategy":"retry","validationCode":"// validate the IP before sending\nfunc validIPArg(ipstr string) bool { return net.ParseIP(ipstr) != nil }","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // retry with backoff / larger deadline\n    } else {\n        // server closed/reset: back off, slow request rate\n    }\n}","preventionTips":["Keep a modest query rate to avoid server-side disconnects/rate limits","Always send well-formed, non-empty IP strings","Set explicit connection deadlines so writes fail predictably","Retry once on reset/broken-pipe before surfacing the error"],"tags":["network","tcp","whois","broken-pipe","write"],"backgroundTag":"broken-pipe","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}