owasp-amass/amass · error

failed to send the request to the WHOIS server: %v

Error message

failed to send the request to the WHOIS server: %v

What it means

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.

Source

Thrown at engine/plugins/whois/bgptools/plugin.go:147

}

func (bt *bgpTools) whois(ctx context.Context, ipstr string) (*bgpToolsRecord, error) {
	dial := amassnet.NewDialContext(3 * time.Second)
	addr := net.JoinHostPort(bt.addr, strconv.Itoa(bt.port))

	_ = bt.rlimit.Wait(ctx)
	ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
	defer cancel()

	conn, err := dial(ctx, "tcp", addr)
	if err != nil {
		return nil, fmt.Errorf("failed to establish a connection with the WHOIS server: %v", err)
	}
	defer func() { _ = conn.Close() }()

	n, err := io.WriteString(conn, fmt.Sprintf("begin\n%s\nend", ipstr))
	if err != nil || n == 0 {
		return nil, fmt.Errorf("failed to send the request to the WHOIS server: %v", err)
	}

	data, err := io.ReadAll(conn)
	if err != nil {
		return nil, fmt.Errorf("error reading the response from the WHOIS server: %v", err)
	}

	record := strings.Split(string(data), "|")
	// Ensure the record contains the necessary details (AutonomousSystem and Netblock)
	if len(record) < 7 {
		return nil, errors.New("received insufficient data from the WHOIS server")
	}

	var r bgpToolsRecord
	for i, f := range record {
		field := strings.TrimSpace(f)

		switch i {

View on GitHub (pinned to 79299dce87)

Solutions

  1. Inspect the wrapped cause (`%v`) — ECONNRESET/broken pipe usually means server-side close or rate limiting
  2. Check whether the IP string passed in is a valid, non-empty IP before calling
  3. Verify the 10s timeout is adequate for the network path; increase the deadline if writes are timing out
  4. Reduce request rate / honor bgp.tools rate limits to avoid being disconnected
  5. Retry the query with backoff; transient resets often succeed on a fresh connection

Example fix

// before
n, err := io.WriteString(conn, fmt.Sprintf("begin\n%s\nend", ipstr))
// after
if net.ParseIP(ipstr) == nil {
    return nil, fmt.Errorf("invalid IP argument: %q", ipstr)
}
conn.SetDeadline(time.Now().Add(10 * time.Second))
n, err := io.WriteString(conn, fmt.Sprintf("begin\n%s\nend\n", ipstr))
Defensive patterns

Strategy: retry

Validate before calling

// validate the IP before sending
func validIPArg(ipstr string) bool { return net.ParseIP(ipstr) != nil }

Try / catch

if err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() {
        // retry with backoff / larger deadline
    } else {
        // server closed/reset: back off, slow request rate
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of owasp-amass/amass@79299dce87 (2026-09-06). Data as JSON: /api/errors/5b585b6cb4c47e31. Report an issue: GitHub.