{"record":{"id":"836b5c703117c5ba","repo":"siyuan-note/siyuan","slug":"failed-to-resolve-host","errorCode":null,"errorMessage":"failed to resolve host: ","messagePattern":"failed to resolve host: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/httprequest.go","lineNumber":52,"sourceCode":"\t\"time\"\n\n\t\"github.com/siyuan-note/httpclient\"\n\tgolangProxy \"golang.org/x/net/proxy\"\n)\n\nconst (\n\tmaxHTTPRequestBytes     = 5 * 1024 * 1024  // text/html、text/plain、application/json 等文本类响应上限\n\tmaxHTTPRequestFileBytes = 10 * 1024 * 1024 // 二进制响应落盘上限\n\tmaxHTTPRequestChars     = 50000\n)\n\n// CheckHostSSRF 校验主机名解析出的 IP 不落在内网/回环等不可达地址段，\n// 防止智能体被诱导发起 SSRF 攻击。web_fetch 与 http_request 共用此校验。\n// https://github.com/siyuan-note/siyuan/security/advisories/GHSA-rg26-cg95-gq6p\nfunc CheckHostSSRF(host string) error {\n\tips, err := net.LookupIP(host)\n\tif err != nil {\n\t\treturn errors.New(\"failed to resolve host: \" + err.Error())\n\t}\n\tfor _, ip := range ips {\n\t\t// 与 SSRFSafeDialer 共用 isPrivateIP，覆盖 NAT64、6to4、Teredo 等 IPv6 过渡地址。\n\t\tif isPrivateIP(ip) {\n\t\t\treturn errors.New(\"access to private/internal IP is prohibited\")\n\t\t}\n\t}\n\treturn nil\n}\n\n// ssrfSafeClient 是智能体出站请求专用的 HTTP 客户端：直连时将目标固定到已校验的公网 IP，\n// 使用代理时则先与用户配置的代理建立隧道，再通过隧道连接固定后的目标 IP，同时保留原始 Host 和 TLS SNI。\n// 两种方式都不会在校验后再次按目标域名解析，避免 DNS 重绑定 TOCTOU 绕过。\n// https://github.com/siyuan-note/siyuan/security/advisories/GHSA-x8gv-g2g3-65fj\nvar ssrfSafeClient = newSSRFSafeClient()\n\nfunc newSSRFSafeClient() *http.Client {\n\treturn newSSRFSafeClientWithResolver(net.DefaultResolver.LookupIPAddr)","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/httprequest.go#L34-L70","documentation":"CheckHostSSRF performs DNS resolution of the target host before any outbound agent request (web_fetch, http_request, generated-image download, skill source download) to block SSRF (see GHSA-rg26-cg95-gq6p). If the host cannot be resolved at all, the request is rejected with this error carrying the DNS failure reason.","triggerScenarios":"HTTPRequest, WebFetch, downloadGeneratedImage, or downloadSkillSource is called with a hostname DNS cannot resolve — a typo'd domain, expired domain, no network/DNS server, or an intranet-only name resolvable only inside a private network.","commonSituations":"Offline machine or broken DNS configuration; a misspelled URL in an AI agent tool call; a hostname valid only on an internal network that the SSRF guard intentionally cannot reach; IPv6-only environments with broken AAAA resolution.","solutions":["Verify the hostname spelling and that it resolves: nslookup <host> or dig <host>","Check network/DNS configuration (resolv.conf, VPN, proxy) and connectivity","Use a fully-qualified public domain; internal hosts are intentionally blocked by the SSRF guard","If DNS is flaky, retry after connectivity is restored — never bypass the check"],"exampleFix":"// before\nfetchPost(\"/api/ai/webFetch\", {url: \"http://intranet-host/data\"})\n// after\nfetchPost(\"/api/ai/webFetch\", {url: \"https://example.com/data\"})","handlingStrategy":"retry","validationCode":"// pre-flight in the caller\nif net.ParseIP(host) == nil {\n    if _, err := net.LookupHost(host); err != nil { /* fail fast: unresolvable host */ }\n}","typeGuard":null,"tryCatchPattern":"if strings.HasPrefix(err.Error(), \"failed to resolve host\") {\n    // surface a DNS/network problem to the user; do not retry in a tight loop\n}","preventionTips":["Verify hostnames before submitting them to agent tools","Check DNS/VPN configuration on the machine","Use public FQDNs; intranet hosts are intentionally blocked","Distinguish transient DNS failures (retry) from NXDOMAIN (fix the name)"],"tags":["network","dns","ssrf","security"],"backgroundTag":"network-request-failed","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}