owasp-amass/amass · error

failed to cast the IPNetRecord

Error message

failed to cast the IPNetRecord

What it means

getRegisteredNetblockEntity expects record.Asset to be an *oamreg.IPNetRecord so it can resolve the registered netblock entity. The type assertion failure means the entity handed to it carries a different asset type. It is a guard against routing non-netblock entities into the netblock registration lookup.

Source

Thrown at engine/plugins/horizontals/plugin.go:499

		return nil, errors.New("failed to cast the DomainRecord")
	}

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

	if ents, err := sess.DB().FindEntitiesByContent(ctx, oam.FQDN, time.Time{}, 1, dbt.ContentFilters{
		"name": dr.Domain,
	}); err == nil && len(ents) == 1 {
		return ents[0], nil
	}

	return nil, fmt.Errorf("failed to obtain the registered domain name FQDN for: %s", dr.Domain)
}

func (h *horizPlugin) getRegisteredNetblockEntity(sess et.Session, record *dbt.Entity) (*dbt.Entity, error) {
	iprec, valid := record.Asset.(*oamreg.IPNetRecord)
	if !valid {
		return nil, errors.New("failed to cast the IPNetRecord")
	}

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

	if ents, err := sess.DB().FindEntitiesByContent(ctx, oam.Netblock, time.Time{}, 1, dbt.ContentFilters{
		"cidr": iprec.CIDR.String(),
	}); err == nil && len(ents) == 1 {
		return ents[0], nil
	}

	return nil, fmt.Errorf("failed to obtain the registered CIDR Netblock for: %s", iprec.CIDR.String())
}

View on GitHub (pinned to 79299dce87)

Solutions

  1. Type-check record.Asset.(*oamreg.IPNetRecord) before calling and silently skip mismatches
  2. Ensure processIPNetRecord is only fed events whose asset is *oamreg.IPNetRecord
  3. Verify DB entity deserialization produces *oamreg.IPNetRecord for netblock registration content

Example fix

// before
nb, err := h.getRegisteredNetblockEntity(sess, record)
if err != nil {
	return err
}

// after
if _, ok := record.Asset.(*oamreg.IPNetRecord); !ok {
	return nil
}
nb, err := h.getRegisteredNetblockEntity(sess, record)
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := record.Asset.(*oamreg.IPNetRecord); !ok {
	return nil // not an IPNetRecord; skip
}

Type guard

func isIPNetRecord(a interface{}) (*oamreg.IPNetRecord, bool) {
	r, ok := a.(*oamreg.IPNetRecord)
	return r, ok
}

Try / catch

if err != nil {
	if strings.Contains(err.Error(), "failed to cast the IPNetRecord") {
		return nil // ignore non-netblock entities
	}
	return err
}

Prevention

When it happens

Trigger: processInScope or processIPNetRecord passes an entity whose Asset is not *oamreg.IPNetRecord (e.g. an IPAddress or Netblock asset instead of the registration record) into getRegisteredNetblockEntity.

Common situations: Event-graph relations forwarding raw netblock/IP assets instead of registration records; new plugins emitting netblock data without wrapping it in oamreg.IPNetRecord; asset type changes after a library upgrade.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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