owasp-amass/amass · error

target must be a FQDN or IPAddress

Error message

target must be a FQDN or IPAddress

What it means

Thrown by support.JARMFingerprint when the target asset is neither an *oamdns.FQDN nor a *network.IPAddress. JARM TLS fingerprinting needs a host string, which is only derivable from those two asset types; anything else makes the function fail with this error. It is an input type-validation error.

Source

Thrown at engine/plugins/support/fingerprinting.go:33

	et "github.com/owasp-amass/amass/v5/engine/types"
	amassnet "github.com/owasp-amass/amass/v5/internal/net"
	oam "github.com/owasp-amass/open-asset-model"
	oamdns "github.com/owasp-amass/open-asset-model/dns"
	"github.com/owasp-amass/open-asset-model/general"
	"github.com/owasp-amass/open-asset-model/network"
)

func JARMFingerprint(sess et.Session, target oam.Asset, portrel *general.PortRelation) (string, error) {
	var ipv6 bool
	var host string

	if fqdn, ok := target.(*oamdns.FQDN); ok {
		host = fqdn.Name
	} else if ip, ok := target.(*network.IPAddress); ok {
		ipv6 = ip.Address.Is6()
		host = ip.Address.String()
	} else {
		return "", errors.New("target must be a FQDN or IPAddress")
	}

	addr := host
	if ipv6 {
		addr = "[" + addr + "]"
	}
	addr += ":" + strconv.Itoa(portrel.PortNumber)

	var results []string
	for _, probe := range jarm.GetProbes(host, portrel.PortNumber) {
		sess.NetSem().Acquire()

		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()

		dial := amassnet.NewDialContext(5 * time.Second)
		c, err := dial(ctx, "tcp", addr)
		sess.NetSem().Release()

View on GitHub (pinned to 79299dce87)

Solutions

  1. Pass an *oamdns.FQDN or *network.IPAddress asset as the target
  2. Resolve/normalize other asset types (e.g. Service -> port on FQDN/IP) before calling
  3. Add a type check in the caller before invoking JARMFingerprint
  4. Skip JARM fingerprinting for unsupported asset types in the calling plugin

Example fix

// before
hash, err := support.JARMFingerprint(session, asset, port)
// after
var target interface{}
switch a := asset.(type) {
case *oamdns.FQDN, *network.IPAddress:
	target = a
default:
	return nil // unsupported asset for JARM
}
hash, err := support.JARMFingerprint(session, target, port)
Defensive patterns

Strategy: validation

Validate before calling

switch t := target.(type) {
case *oamdns.FQDN, *network.IPAddress:
	// ok
default:
	return fmt.Errorf("JARM requires FQDN or IPAddress, got %T", target)
}

Type guard

func jarmCapable(target asset.Asset) bool {
	switch target.(type) {
	case *oamdns.FQDN, *network.IPAddress:
		return true
	}
	return false
}

Try / catch

hash, err := support.JARMFingerprint(session, target, port)
if err != nil {
	if strings.Contains(err.Error(), "target must be a FQDN or IPAddress") {
		return nil // unsupported asset type; skip JARM
	}
	return err
}

Prevention

When it happens

Trigger: JARMFingerprint is called (e.g. from query) with a target asset of any other type — Netblock, Service, ASN, nil, etc. — so both type assertions fail and the else branch returns the error.

Common situations: Calling JARMFingerprint directly with a raw string or unsupported asset; pipeline passing domain/service assets without resolving to FQDN or IP first; passing a nil asset.

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/2b3b626c0ea76463. Report an issue: GitHub.