{"record":{"id":"2a19442e75e55f8e","repo":"juanfont/headscale","slug":"hostname-contains-invalid-ip-address","errorCode":null,"errorMessage":"hostname contains invalid IP address","messagePattern":"hostname contains invalid IP address","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hscontrol/policy/v2/types.go","lineNumber":126,"sourceCode":"\tErrInvalidUsername             = errors.New(\"username must contain @\")\n\tErrUserNotFound                = errors.New(\"user not found\")\n\tErrMultipleUsersFound          = errors.New(\"multiple users found\")\n\tErrInvalidGroupFormat          = errors.New(\"group must start with 'group:'\")\n\tErrInvalidTagFormat            = errors.New(\"tag must start with 'tag:'\")\n\tErrInvalidHostname             = errors.New(\"invalid hostname\")\n\tErrHostResolve                 = errors.New(\"error resolving host\")\n\tErrInvalidPrefix               = errors.New(\"invalid prefix\")\n\tErrInvalidAutogroup            = errors.New(\"invalid autogroup\")\n\tErrUnknownAutogroup            = errors.New(\"unknown autogroup\")\n\tErrHostportMissingColon        = errors.New(\"hostport must contain a colon\")\n\tErrTypeNotSupported            = errors.New(\"type not supported\")\n\tErrInvalidAlias                = errors.New(\"invalid alias format\")\n\tErrInvalidAutoApprover         = errors.New(\"invalid auto approver format\")\n\tErrInvalidOwner                = errors.New(\"invalid owner format\")\n\tErrGroupNotDefined             = errors.New(\"group not defined in policy\")\n\tErrInvalidGroupMember          = errors.New(\"invalid group member type\")\n\tErrGroupValueNotArray          = errors.New(\"group value must be an array of users\")\n\tErrInvalidHostIP               = errors.New(\"hostname contains invalid IP address\")\n\tErrTagNotDefined               = errors.New(\"tag not found\")\n\tErrAutoApproverNotAlias        = errors.New(\"auto approver is not an alias\")\n\tErrInvalidACLAction            = errors.New(\"invalid ACL action\")\n\tErrInvalidSSHAction            = errors.New(\"invalid SSH action\")\n\tErrInvalidProtocolNumber       = errors.New(\"invalid protocol number\")\n\tErrProtocolLeadingZero         = errors.New(\"leading 0 not permitted in protocol number\")\n\tErrProtocolOutOfRange          = errors.New(\"protocol number out of range (0-255)\")\n\tErrAutogroupNotSupported       = errors.New(\"autogroup not supported in headscale\")\n\tErrAutogroupInternetSrc        = errors.New(\"autogroup:internet can only be used in ACL destinations\")\n\tErrAutogroupSelfSrc            = errors.New(\"\\\"autogroup:self\\\" not valid on the src side of a rule\")\n\tErrAutogroupNotSupportedACLSrc = errors.New(\"autogroup not supported for ACL sources\")\n\tErrAutogroupNotSupportedACLDst = errors.New(\"autogroup not supported for ACL destinations\")\n\tErrAutogroupDangerAllDst       = errors.New(\"cannot use autogroup:danger-all as a dst\")\n\tErrAutogroupNotSupportedSSHSrc = errors.New(\"autogroup not supported for SSH sources\")\n\tErrAutogroupNotSupportedSSHDst = errors.New(\"autogroup not supported for SSH destinations\")\n\tErrHostNotDefined              = errors.New(\"host not defined in policy\")\n\tErrSSHSourceAliasNotSupported  = errors.New(\"alias not supported for SSH source\")\n\tErrSSHDestAliasNotSupported    = errors.New(\"alias not supported for SSH destination\")","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/hscontrol/policy/v2/types.go#L108-L144","documentation":"Returned by Hosts.UnmarshalJSON (hscontrol/policy/v2/types.go:1426) when the value of an entry in the policy's \"hosts\" map cannot be parsed as an IP address or prefix. Hosts are static DNS aliases mapping a name to an IP/CIDR; the value goes through Prefix.parseString and any parse failure is reported with the hostname and the invalid value.","triggerScenarios":"A policy with \"hosts\": {\"example-host-1\": \"not-an-ip\"}, \"hosts\": {\"h\": \"192.168.1\"} (malformed octets), or a DNS name as the value (\"hosts\": {\"alias\": \"example.com\"} — dynamic resolution is not supported in hosts). Fails when the policy is loaded at startup or via `headscale policy set`.","commonSituations":"Expecting hosts entries to work like /etc/hosts with domain names on the right-hand side, typos in IPv6 addresses, or pasting a hostname where an IP is required. Users coming from other ACL systems that allow DNS targets hit this often.","solutions":["Use a valid IP address or CIDR as the host value: \"example-host-1\": \"100.100.100.100\" or \"10.0.0.0/24\"","If you need a DNS name, put it on the left side and the IP on the right side; hosts entries cannot resolve domains","Check IPv6 entries include the full address form (e.g. \"fd7a:115c:a1e0::1\")"],"exampleFix":"// before\n\"hosts\": {\n  \"example-host-1\": \"example.com\"\n}\n\n// after\n\"hosts\": {\n  \"example-host-1\": \"100.100.100.100\"\n}","handlingStrategy":"validation","validationCode":"// Pre-check every hosts value parses as a prefix\nfor name, val := range hostsMap {\n\tif _, err := netip.ParsePrefix(val); err != nil {\n\t\tif _, err2 := netip.ParseAddr(val); err2 != nil {\n\t\t\treturn fmt.Errorf(\"host %s has invalid address %s\", name, val)\n\t\t}\n\t}\n}","typeGuard":"func isInvalidHostIP(err error) bool {\n\treturn errors.Is(err, policy.ErrInvalidHostIP)\n}","tryCatchPattern":"if err := json.Unmarshal(b, &p); err != nil {\n\tif errors.Is(err, policy.ErrInvalidHostIP) {\n\t\t// message names the hostname and bad value; surface to the operator\n\t\treturn fmt.Errorf(\"invalid hosts entry: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Never put DNS names on the right side of a hosts entry — hosts maps name -> IP/CIDR only","Generate hosts entries from IPAM data rather than hand-typing addresses","Run `headscale policy check` after editing hosts"],"tags":["policy","json","dns","ip-address","validation"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}