{"record":{"id":"321c5c3b77a1da4f","repo":"siyuan-note/siyuan","slug":"host-has-no-ip-address","errorCode":null,"errorMessage":"host has no IP address: ","messagePattern":"host has no IP address: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/httprequest.go","lineNumber":169,"sourceCode":"\t\t\tport = \"443\"\n\t\tdefault:\n\t\t\treturn \"\", errors.New(\"URL must start with http:// or https://\")\n\t\t}\n\t}\n\n\tif ip := net.ParseIP(host); ip != nil {\n\t\tif isPrivateIP(ip) {\n\t\t\treturn \"\", errors.New(\"access to private/internal IP is prohibited\")\n\t\t}\n\t\treturn net.JoinHostPort(ip.String(), port), nil\n\t}\n\n\tips, err := t.lookupIPAddr(ctx, host)\n\tif err != nil {\n\t\treturn \"\", errors.New(\"failed to resolve host: \" + err.Error())\n\t}\n\tif len(ips) == 0 {\n\t\treturn \"\", errors.New(\"host has no IP address: \" + host)\n\t}\n\tfor _, ipAddr := range ips {\n\t\tif isPrivateIP(ipAddr.IP) {\n\t\t\treturn \"\", errors.New(\"access to private/internal IP is prohibited\")\n\t\t}\n\t}\n\treturn net.JoinHostPort(ips[0].IP.String(), port), nil\n}\n\nfunc cloneURL(src *url.URL) *url.URL {\n\tret := *src\n\treturn &ret\n}\n\nfunc dialProxyTunnel(ctx context.Context, proxyURL *url.URL, targetAddr string) (net.Conn, *bufio.Reader, error) {\n\tproxyAddr, err := proxyAddress(proxyURL)\n\tif err != nil {\n\t\treturn nil, nil, err","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/util/httprequest.go#L151-L187","documentation":"After a successful DNS lookup, resolvePublicTarget checks whether any IP addresses were returned. An empty list means the resolver answered but produced no usable addresses, so dialing is impossible and the error 'host has no IP address' is thrown. This prevents silent empty-address dial failures later.","triggerScenarios":"lookupIPAddr returns zero IPs for the host — e.g. a hostname with only records the resolver filtered out, or an empty/edge-case host string that parses but has no addresses.","commonSituations":"DNS zone missing A/AAAA records for a name that exists (CNAME-only misconfig); hosts file entries removed; freshly registered domain with no records; IPv6-only resolver returning no AAAA while IPv4 unavailable.","solutions":["Add A/AAAA records for the hostname in DNS, or point the request at an IP-backed public hostname","Confirm with `dig <host> A` and `dig <host> AAAA` that at least one record exists","Check whether the local resolver filters records (security software, DNS filtering)","Correct typos — a valid-but-recordless name is often a misspelling"],"exampleFix":"// before\n\"https://api.internal.example.net\"  // no A record\n// after\n\"https://api.example.com\"            // resolvable public host","handlingStrategy":"validation","validationCode":"if len(ips) == 0 {\n    return fmt.Errorf(\"host %q resolves to no IP addresses\", host)\n}","typeGuard":"func hasIPAddress(host string) bool {\n    ips, err := net.LookupIP(host)\n    return err == nil && len(ips) > 0\n}","tryCatchPattern":null,"preventionTips":["Confirm A/AAAA records exist for the hostname (dig A / dig AAAA)","Fix DNS zones that publish CNAME-only or filtered answers","Re-check spelling — recordless names are usually typos","Check DNS filtering software that may strip records"],"tags":["network","dns","ssrf"],"backgroundTag":"empty-result-set","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}