{"record":{"id":"436399b6c2b27f85","repo":"netbirdio/netbird","slug":"not-a-valid-host-subnet-or-domain","errorCode":null,"errorMessage":"not a valid host, subnet, or domain","messagePattern":"not a valid host, subnet, or domain","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"management/server/networks/resources/types/resource.go","lineNumber":196,"sourceCode":"\n// GetResourceType returns the type of the resource based on the address\nfunc GetResourceType(address string) (NetworkResourceType, string, netip.Prefix, error) {\n\tif prefix, err := netip.ParsePrefix(address); err == nil {\n\t\tif prefix.Bits() == 32 || prefix.Bits() == 128 {\n\t\t\treturn Host, \"\", prefix, nil\n\t\t}\n\t\treturn Subnet, \"\", prefix, nil\n\t}\n\n\tif ip, err := netip.ParseAddr(address); err == nil {\n\t\treturn Host, \"\", netip.PrefixFrom(ip, ip.BitLen()), nil\n\t}\n\n\tif _, err := nbDomain.ValidateDomains([]string{address}); err == nil {\n\t\treturn Domain, address, netip.Prefix{}, nil\n\t}\n\n\treturn \"\", \"\", netip.Prefix{}, errors.New(\"not a valid host, subnet, or domain\")\n}\n","sourceCodeStart":178,"sourceCodeEnd":198,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/management/server/networks/resources/types/resource.go#L178-L198","documentation":"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: ...\".","triggerScenarios":"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!\".","commonSituations":"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.","solutions":["Send a bare IP (\"192.0.2.1\"), a CIDR (\"10.0.0.0/8\"), or a plain domain (\"example.com\").","Strip schemes, ports, paths, and whitespace before submitting an address.","Punycode-convert unicode domains or let a client-side domain validator do it before the request."],"exampleFix":"// before\nresource.Address = \"https://example.com\"\n// after\nresource.Address = \"example.com\"","handlingStrategy":"validation","validationCode":"func isClassifiableAddress(a string) error {\n    if _, err := netip.ParsePrefix(a); err == nil { return nil }\n    if _, err := netip.ParseAddr(a); err == nil { return nil }\n    if _, err := domain.ValidateDomains([]string{a}); err == nil { return nil }\n    return fmt.Errorf(\"%q is not a valid host, subnet, or domain\", a)\n}\n\nif err := isClassifiableAddress(resource.Address); err != nil {\n    return err\n}","typeGuard":"func validResourceAddress(a string) bool {\n    if _, err := netip.ParsePrefix(a); err == nil { return true }\n    if _, err := netip.ParseAddr(a); err == nil { return true }\n    _, err := domain.ValidateDomains([]string{a})\n    return err == nil\n}","tryCatchPattern":"if _, _, _, err := types.GetResourceType(resource.Address); err != nil {\n    return fmt.Errorf(\"failed to get resource type: %w\", err) // surfaces 'not a valid host, subnet, or domain'\n}","preventionTips":["Offer three explicit input modes (IP, CIDR, domain) in UIs instead of one free-text field.","Strip schemes, ports, paths, and whitespace from addresses before submitting.","For subnets always include the /bits suffix; a bare address is classified as a Host."],"tags":["networks","resources","validation","address-parsing"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}