owasp-amass/amass · warning

unexpected response

Error message

unexpected response

What it means

dnsQuery in engine/plugins/support/resolvers.go returns errors.New("unexpected response") as a catch-all when the DNS response Rcode is neither RcodeNameError nor RcodeSuccess — e.g. SERVFAIL, REFUSED, NOTIMP — or otherwise does not fit the handled cases. It indicates the trusted resolver gave an unusable answer rather than a definitive existence verdict.

Source

Thrown at engine/plugins/support/resolvers.go:139

	if dom, err := publicsuffix.EffectiveTLDPlusOne(name); err == nil && dom != "" {
		return r.WildcardDetected(ctx, resp, dom)
	}
	return false
}

func dnsQuery(ctx context.Context, msg *dns.Msg, r *pool.Pool) (*dns.Msg, error) {
	if resp, err := r.Exchange(ctx, msg); err != nil {
		return nil, err
	} else if resp.Rcode == dns.RcodeNameError {
		return nil, ErrNameDoesNotExist
	} else if resp.Rcode == dns.RcodeSuccess {
		if len(resp.Answer) == 0 {
			return nil, ErrNoRecordOfThisType
		}
		return resp, nil
	}
	return nil, errors.New("unexpected response")
}

func trustedResolvers() *pool.Pool {
	timeout := 250 * time.Millisecond
	cpus := runtime.NumCPU()
	// wildcard detector
	serv := servers.NewNameserver("8.8.4.4")
	wconns := conn.New(cpus, selectors.NewSingle(timeout, serv))
	detector = wildcards.NewDetector(serv, wconns, nil)
	// the server pool
	var servs []types.Nameserver
	for _, r := range baselineResolvers {
		servs = append(servs, servers.NewNameserver(r.address))
	}
	sel := selectors.NewRoundRobin(timeout, servs...)
	//sel := selectors.NewAuthoritative(timeout, servers.NewNameserver)
	conns := conn.New(cpus, sel)
	return pool.New(0, sel, conns, nil)

View on GitHub (pinned to 79299dce87)

Solutions

  1. Retry, possibly with a different resolver from the pool — many RCodes are transient.
  2. Inspect the actual Rcode with dig @resolver name TYPE to identify SERVFAIL vs REFUSED.
  3. Check resolver reachability/firewall rules and whether the resolver rate-limits your client.
  4. Ensure queries are well-formed (correct name/qtype); FORMERR may indicate a malformed message.

Example fix

// before
rr, err := support.PerformQuery(ctx, name, dns.TypeA)
if err != nil {
    return err
}
// after
rr, err := support.PerformQuery(ctx, name, dns.TypeA)
if err != nil {
    if strings.Contains(err.Error(), "unexpected response") {
        log.Warn("unusable DNS response (server failure/refused), retrying later", "name", name)
        return nil
    }
    return err
}
Defensive patterns

Strategy: retry

Validate before calling

// Verify resolver health before queries
r := &net.Resolver{}
_, err := r.LookupHost(context.Background(), "google.com")
if err != nil { log.Warn("resolver unhealthy") }

Try / catch

rr, err := support.PerformQuery(ctx, name, dns.TypeA)
if err != nil && strings.Contains(err.Error(), "unexpected response") {
    select {
    case <-time.After(backoff):
        rr, err = support.PerformQuery(ctx, name, dns.TypeA)
    }
}

Prevention

When it happens

Trigger: Calling support.PerformQuery (which calls dnsQuery) and receiving a response whose Rcode is anything other than NOERROR or NXDOMAIN (SERVFAIL, REFUSED, FORMERR, etc.).

Common situations: Resolver refusing queries (REFUSED) due to ACLs or rate limiting; SERVFAIL from broken DNSSEC chains or authoritative server issues; misbehaving middleboxes intercepting DNS traffic.

Related errors


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