owasp-amass/amass · warning

no PTR records found for %s

Error message

no PTR records found for %s

What it means

lookupPTRRecordName queries the graph database for outgoing 'ptr_record' edges from the given IP entity. If the query errors or yields no edges, no reverse-DNS name is available for the IP, so it returns this error. It signals that the horizontal enumeration step cannot proceed for this asset.

Source

Thrown at engine/plugins/horizontals/ipaddr.go:61

		return nil
	}

	h.process(e, ip, fqdn)
	return nil
}

func (h *horaddr) lookupPTRRecordName(sess et.Session, ip *dbt.Entity) (*dbt.Entity, error) {
	since, err := support.TTLStartTime(sess.Config(), string(oam.IPAddress), string(oam.FQDN), h.plugin.name)
	if err != nil || since.IsZero() {
		return nil, errors.New("IPAddress -> FQDN transformation not supported")
	}

	ctx, cancel := context.WithTimeout(sess.Ctx(), 30*time.Second)
	defer cancel()

	edges, err := sess.DB().OutgoingEdges(ctx, ip, since, "ptr_record")
	if err != nil || len(edges) == 0 {
		return nil, fmt.Errorf("no PTR records found for %s", ip.Asset.Key())
	}

	ptr, err := sess.DB().FindEntityById(ctx, edges[0].ToEntity.ID)
	if err != nil {
		return nil, fmt.Errorf("failed to acquire the entity with ID: %s", edges[0].ToEntity.ID)
	}

	return ptr, nil
}

func (h *horaddr) lookupPTRRecordData(sess et.Session, ptr *dbt.Entity) (*dbt.Entity, error) {
	since, err := support.TTLStartTime(sess.Config(), string(oam.FQDN), string(oam.FQDN), h.plugin.name)
	if err != nil || since.IsZero() {
		return nil, errors.New("FQDN -> FQDN transformation not supported")
	}

	ctx, cancel := context.WithTimeout(sess.Ctx(), 30*time.Second)
	defer cancel()

View on GitHub (pinned to 79299dce87)

Solutions

  1. Verify the IP actually has a PTR record: dig -x <ip> or a reverse-DNS API.
  2. Check the 'since' timestamp passed to OutgoingEdges — widening the window may reveal existing edges.
  3. Ensure a data source that discovers PTR records has run and its data was committed to the graph.
  4. Handle this error gracefully in check() and skip the IP rather than aborting the scan.
  5. If OutgoingEdges returned err != nil, log the underlying DB error and investigate the graph store.

Example fix

// before
edges, err := sess.DB().OutgoingEdges(ctx, ip, since, "ptr_record")
if err != nil || len(edges) == 0 {
	return nil, fmt.Errorf("no PTR records found for %s", ip.Asset.Key())
}
// after
edges, err := sess.DB().OutgoingEdges(ctx, ip, since, "ptr_record")
if err != nil {
	return nil, fmt.Errorf("no PTR records found for %s: %w", ip.Asset.Key(), err)
}
if len(edges) == 0 {
	return nil, fmt.Errorf("no PTR records found for %s", ip.Asset.Key()) // typed sentinel for graceful skip
}
Defensive patterns

Strategy: try-catch

Validate before calling

if strings.TrimSpace(ipStr) == "" || net.ParseIP(ipStr) == nil {
	return fmt.Errorf("invalid IP, skip PTR lookup")
}

Try / catch

ptr, err := lookupPTRRecordName(sess, ipEnt)
if err != nil {
	// no PTR for this IP is common: log at debug and skip
	return nil
}

Prevention

When it happens

Trigger: sess.DB().OutgoingEdges(ctx, ip, since, "ptr_record") returns err != nil, or returns zero edges because no PTR relationship was ever discovered/stored for this IP within the 'since' time window.

Common situations: IP has no reverse DNS configured at all (very common for cloud/provider IPs); data was released (since timestamp) so old edges are filtered out; DB query failure (locked/closed store); the IP entity was created by a source that does not perform PTR lookups.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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