owasp-amass/amass · warning
failed to obtain the subject contact record
Error message
failed to obtain the subject contact record
What it means
horTlsCert.lookup calls getContactRecord(sess, tlsent, "subject_contact") to fetch the certificate's subject contact entity from the graph; when that returns an error, the underlying cause is discarded and this generic error is raised. It means no subject contact relation was found (or the lookup failed) for the TLS certificate entity.
Source
Thrown at engine/plugins/horizontals/tls_cert.go:48
if !ok {
return errors.New("failed to cast the TLSCertificate asset")
}
// check if scope expansion is allowed
if e.Session.Config().Rigid {
return nil
}
if orgs, err := h.lookup(e.Session, e.Entity); err == nil && len(orgs) > 0 {
h.process(e, c, orgs)
}
return nil
}
func (h *horTlsCert) lookup(sess et.Session, tlsent *dbt.Entity) ([]*dbt.Entity, error) {
cr, err := h.plugin.getContactRecord(sess, tlsent, "subject_contact")
if err != nil {
return nil, errors.New("failed to obtain the subject contact record")
}
orgs, err := h.plugin.getContactRecordOrganizations(sess, cr)
if err != nil {
return nil, errors.New("failed to obtain the subject organizations")
}
return orgs, nil
}
func (h *horTlsCert) process(e *et.Event, c *oamcert.TLSCertificate, orgs []*dbt.Entity) {
// check if the TLS certificate subject common name is in scope
if _, conf := e.Session.Scope().IsAssetInScope(&oamdns.FQDN{Name: c.SubjectCommonName}, 0); conf > 0 {
return
}
var found bool
for _, o := range orgs {View on GitHub (pinned to 79299dce87)
Solutions
- Wrap the original error instead of discarding it: fmt.Errorf("failed to obtain the subject contact record: %w", err) to see the real cause
- Verify the data sources that create subject_contact relations are enabled in config
- Make lookup tolerant: if the contact record is missing, return (nil, nil) and skip scope-expansion processing
Example fix
// before
cr, err := h.plugin.getContactRecord(sess, tlsent, "subject_contact")
if err != nil {
return nil, errors.New("failed to obtain the subject contact record")
}
// after
cr, err := h.plugin.getContactRecord(sess, tlsent, "subject_contact")
if err != nil {
if errors.Is(err, dbt.ErrNotFound) {
return nil, nil
}
return nil, fmt.Errorf("failed to obtain the subject contact record: %w", err)
} Defensive patterns
Strategy: fallback
Validate before calling
var cr *dbt.Entity
ents, _ := sess.DB().FindEntitiesByContent(ctx, oam.ContactRecord, time.Time{}, 1, filters)
if len(ents) == 0 {
return nil, nil // no subject contact; skip expansion
} Try / catch
orgs, err := h.lookup(sess, tlsent)
if err != nil {
log.WithError(err).Debug("no subject contact record; skipping TLS expansion")
return nil
} Prevention
- Enable the data sources that create subject_contact relations
- Wrap underlying errors with %w so causes are diagnosable
- Check relation existence in the graph before TLS-driven scope expansion
When it happens
Trigger: A TLSCertificate entity exists in the graph but has no subject_contact relation to a ContactRecord — e.g. the certificate data source did not provide subject contact info, or getContactRecord's DB query fails and its error is swallowed here.
Common situations: Certificates scraped from sources lacking contact metadata; running with data sources disabled so contact records are never created; relations pruned by TTL cleanup before the horizontals plugin processes the certificate.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- failed to obtain the subject organizations
- zero locations found
- failed to extract the locations
- failed to cast the DomainRecord
- failed to cast the IPNetRecord
AI-assisted analysis of owasp-amass/amass@79299dce87 (2026-09-06).
Data as JSON: /api/errors/60b6c901bda8d065.
Report an issue: GitHub.