owasp-amass/amass · warning · ErrFailedMaxDNSAttempts

failed the maximum number of DNS attempts

Error message

failed the maximum number of DNS attempts

What it means

ErrFailedMaxDNSAttempts is a sentinel error returned when the resolver exhausts its retry budget — the internal query function gives up after repeatedly failing to obtain a valid response from available resolvers (timeouts, SERVFAIL, transient network errors). Unlike ErrNameDoesNotExist, it is transient: another attempt later may succeed. Callers in engine/plugins/dns (cname.go, ip.go) log a warning instead of treating it as a hard failure.

Source

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

	"runtime"
	"strings"
	"time"

	"github.com/miekg/dns"
	"github.com/owasp-amass/resolve/conn"
	"github.com/owasp-amass/resolve/pool"
	"github.com/owasp-amass/resolve/selectors"
	"github.com/owasp-amass/resolve/servers"
	"github.com/owasp-amass/resolve/types"
	"github.com/owasp-amass/resolve/utils"
	"github.com/owasp-amass/resolve/wildcards"
	"golang.org/x/net/publicsuffix"
)

var (
	ErrNameDoesNotExist     = errors.New("name does not exist")
	ErrNoRecordOfThisType   = errors.New("no record of this type")
	ErrFailedMaxDNSAttempts = errors.New("failed the maximum number of DNS attempts")
)

type baseline struct {
	address string
	qps     int
}

// baselineResolvers is a list of trusted public DNS resolvers.
var baselineResolvers = []baseline{
	{"8.8.8.8", 5}, // Google Primary
	//	{"8.8.4.4", 5},         // Google Secondary
	{"95.85.95.85", 2},     // Gcore DNS Primary
	{"2.56.220.2", 2},      // Gcore DNS Secondary
	{"76.76.2.0", 2},       // ControlD Primary
	{"76.76.10.0", 2},      // ControlD Secondary
	{"9.9.9.9", 2},         // Quad9 Primary
	{"149.112.112.112", 2}, // Quad9 Secondary
	{"208.67.222.222", 2},  // Cisco OpenDNS Home Primary

View on GitHub (pinned to 79299dce87)

Solutions

  1. Retry the lookup later — the error is transient by design.
  2. Check local DNS configuration (/etc/resolv.conf) and network reachability to the configured resolvers.
  3. Reduce query concurrency/rate to avoid resolver throttling and increase per-query timeouts.
  4. Log and continue, as the plugin handlers do (session Log().Warn), rather than aborting the enumeration.

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 err == support.ErrFailedMaxDNSAttempts {
        log.Warn("DNS lookup exhausted retries, will retry later", "name", name)
        return nil
    }
    return err
}
Defensive patterns

Strategy: retry

Validate before calling

// Check DNS connectivity before running bulk enumeration
r := &net.Resolver{}
_, err := r.LookupHost(context.Background(), "example.com")
if err != nil { log.Fatal("DNS unavailable: ", err) }

Type guard

func isMaxDNSAttempts(err error) bool { return errors.Is(err, support.ErrFailedMaxDNSAttempts) }

Try / catch

rr, err := support.PerformQuery(ctx, name, dns.TypeA)
if errors.Is(err, support.ErrFailedMaxDNSAttempts) {
    time.Sleep(backoff)
    rr, err = support.PerformQuery(ctx, name, dns.TypeA)
}

Prevention

When it happens

Trigger: Calling support.PerformQuery/query when every DNS attempt to the resolver pool fails (network timeouts, resolver unavailability, repeated non-success RCodes) until the maximum retry count is reached.

Common situations: Running bulk enumeration on a flaky network or behind a firewall blocking port 53; resolver rate-limiting the client; DNSSEC validation failures causing repeated SERVFAIL; container/VM without working DNS configuration.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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