larksuite/cli · error
blocked download target: local/internal host is not allowed
Error message
blocked download target: local/internal host is not allowed
What it means
This is the SSRF guard of the download path: pinDownloadRequestTargetToIP rejects the request when the resolved target IP is nil or is a restricted (loopback, link-local, private, etc.) address. The download flow validates the host once, then pins the connection to that validated IP so DNS cannot be re-resolved to an internal address later. Hitting this error means the destination resolved to a local/internal IP, which the CLI refuses to contact.
Source
Thrown at internal/validate/url.go:389
}, true
}
func cloneDownloadHTTPTransport(source *http.Transport) *http.Transport {
cloned := source.Clone()
if cloned.TLSNextProto == nil {
if _, ok := source.TLSNextProto["h2"]; ok {
cloned.ForceAttemptHTTP2 = true
}
}
return cloned
}
func pinDownloadRequestTargetToIP(req *http.Request, targetIP net.IP) (*http.Request, error) {
if req == nil || req.URL == nil {
return nil, fmt.Errorf("download request URL is missing")
}
if targetIP == nil || isRestrictedDownloadIP(targetIP) {
return nil, fmt.Errorf("blocked download target: local/internal host is not allowed")
}
originalHost := req.URL.Host
pinnedHost := targetIP.String()
if port := req.URL.Port(); port != "" {
pinnedHost = net.JoinHostPort(pinnedHost, port)
} else if strings.Contains(pinnedHost, ":") {
pinnedHost = "[" + pinnedHost + "]"
}
pinned := req.Clone(req.Context())
pinnedURL := *req.URL
pinnedURL.Host = pinnedHost
pinned.URL = &pinnedURL
pinned.Host = originalHost
return pinned, nil
}
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Use a public internet URL for the download target
- Verify DNS resolution of the hostname with dig/nslookup; if it returns a private IP, the host is not a valid public download endpoint
- If this is a legitimate internal download, use the approved internal transfer mechanism instead of the public download path
- Check for typos in the scheme/host (e.g. localhost vs the real host)
Example fix
// before dlURL := "http://127.0.0.1:8080/file.bin" // blocked // after dlURL := "https://open.feishu.cn/file.bin" // public target passes SSRF guard
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check the resolved target before calling the download API
ips, err := net.LookupIP(host)
if err != nil { return err }
for _, ip := range ips {
if ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {
return fmt.Errorf("%s resolves to restricted IP %s; use a public URL", host, ip)
}
} Type guard
func isPublicIP(ip net.IP) bool {
return ip != nil && !ip.IsLoopback() && !ip.IsPrivate() && !ip.IsLinkLocalUnicast() && !ip.IsUnspecified()
} Try / catch
if err := download(url); err != nil && strings.Contains(err.Error(), "local/internal host is not allowed") {
return fmt.Errorf("download target %s is internal/blocked by SSRF policy: %w", url, err)
} Prevention
- Use public HTTPS endpoints for downloads
- Resolve the hostname yourself before downloading to catch private IPs early
- Watch for redirects to internal hosts; keep redirects enabled only within the validated target
- Treat this error as a signal of misconfiguration or a suspicious URL, not a transient failure
When it happens
Trigger: The URL host resolves to 127.0.0.1/::1, 169.254.x.x, RFC1918 (10/8, 172.16/12, 192.168/16), or another address matched by isRestrictedDownloadIP; or no IP could be determined (targetIP nil).
Common situations: Pointing a download at localhost or an internal service by mistake; a DNS name (or attacker-controlled redirect) resolving to an internal IP; IPv6 loopback addresses; misconfigured download URL in config using an internal hostname.
Related errors
- local/internal host is not allowed
- blocked redirect target: %w
- official skills index redirected to non-HTTPS URL: %s
- only http/https URLs are supported
- URL host is required
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/1b53852eeff80d22.
Report an issue: GitHub.