netbirdio/netbird · error

not a valid host, subnet, or domain

Error message

not a valid host, subnet, or domain

What it means

types.GetResourceType classifies a network resource address by trying netip.ParsePrefix (a CIDR is a Host if /32 or /128, otherwise a Subnet), then netip.ParseAddr (bare IP is a Host), then nbDomain.ValidateDomains (a Domain, with punycode conversion). When all three fail it returns this error. Callers such as UpdateResource (manager.go:215) wrap it as "failed to get resource type: ...".

Source

Thrown at management/server/networks/resources/types/resource.go:196

// GetResourceType returns the type of the resource based on the address
func GetResourceType(address string) (NetworkResourceType, string, netip.Prefix, error) {
	if prefix, err := netip.ParsePrefix(address); err == nil {
		if prefix.Bits() == 32 || prefix.Bits() == 128 {
			return Host, "", prefix, nil
		}
		return Subnet, "", prefix, nil
	}

	if ip, err := netip.ParseAddr(address); err == nil {
		return Host, "", netip.PrefixFrom(ip, ip.BitLen()), nil
	}

	if _, err := nbDomain.ValidateDomains([]string{address}); err == nil {
		return Domain, address, netip.Prefix{}, nil
	}

	return "", "", netip.Prefix{}, errors.New("not a valid host, subnet, or domain")
}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Send a bare IP ("192.0.2.1"), a CIDR ("10.0.0.0/8"), or a plain domain ("example.com").
  2. Strip schemes, ports, paths, and whitespace before submitting an address.
  3. Punycode-convert unicode domains or let a client-side domain validator do it before the request.

Example fix

// before
resource.Address = "https://example.com"
// after
resource.Address = "example.com"
Defensive patterns

Strategy: validation

Validate before calling

func isClassifiableAddress(a string) error {
    if _, err := netip.ParsePrefix(a); err == nil { return nil }
    if _, err := netip.ParseAddr(a); err == nil { return nil }
    if _, err := domain.ValidateDomains([]string{a}); err == nil { return nil }
    return fmt.Errorf("%q is not a valid host, subnet, or domain", a)
}

if err := isClassifiableAddress(resource.Address); err != nil {
    return err
}

Type guard

func validResourceAddress(a string) bool {
    if _, err := netip.ParsePrefix(a); err == nil { return true }
    if _, err := netip.ParseAddr(a); err == nil { return true }
    _, err := domain.ValidateDomains([]string{a})
    return err == nil
}

Try / catch

if _, _, _, err := types.GetResourceType(resource.Address); err != nil {
    return fmt.Errorf("failed to get resource type: %w", err) // surfaces 'not a valid host, subnet, or domain'
}

Prevention

When it happens

Trigger: CreateResource/UpdateResource with an address that is none of the three forms: "" (empty), "192.0.2.1/33" (invalid prefix bits), "example.com/" (trailing slash), "host name" (space), "192.0.2.1:8080" (port suffix), or "not_a domain!".

Common situations: Free-text address fields in UIs or scripts with no client-side normalization; forgetting the CIDR slash for subnets ("10.0.0.0" parses as a Host, not a subnet); pasting URLs ("https://example.com") instead of bare domains; empty submissions from forms.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/436399b6c2b27f85. Report an issue: GitHub.