weaviate/weaviate · error
refusing to dial internal address %q
Error message
refusing to dial internal address %q
What it means
ssrfDialGuard blocks outbound connections whose resolved IP is internal (loopback, private ranges, link-local, etc.) via isDisallowedIP. Because it inspects the resolved ip:port, DNS names that resolve to internal addresses are also caught, defending against SSRF even when string-level URL validation passed.
Source
Thrown at usecases/modulecomponents/base_client.go:62
return &http.Client{
Transport: &retryTransport{base: transport, timeout: timeout},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}
// ssrfDialGuard blocks connections to internal addresses. address is the
// resolved "ip:port", so a host that resolves to an internal IP is caught here
// even if it slipped past ValidateBaseURL's string-level checks.
func ssrfDialGuard(network, address string, c syscall.RawConn) error {
host, _, err := net.SplitHostPort(address)
if err != nil {
return fmt.Errorf("invalid dial address %q: %w", address, err)
}
if ip := net.ParseIP(host); ip != nil && isDisallowedIP(ip) {
return fmt.Errorf("refusing to dial internal address %q", address)
}
return nil
}
View on GitHub (pinned to 75aa4b6d11)
Solutions
- Point the module baseUrl at a genuinely public, routable endpoint
- If the internal endpoint is intentional (self-hosted inference), deploy it on a routable address or use the supported configuration to allow it
- Check DNS resolution of the hostname — it may resolve to a private IP unexpectedly
Example fix
// before baseURL := "http://127.0.0.1:8080" // after baseURL := "https://api.example-inference.com"
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(baseURL)
if err != nil {
return err
}
ips, err := net.LookupIP(u.Hostname())
if err != nil {
return err
}
for _, ip := range ips {
if ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() {
return fmt.Errorf("%s resolves to internal IP %s — will be blocked by SSRF guard", u.Host, ip)
}
} Try / catch
_, err := client.Do(req)
if err != nil && strings.Contains(err.Error(), "refusing to dial internal address") {
return fmt.Errorf("endpoint blocked by SSRF protection; use a public endpoint: %w", err)
} Prevention
- Use public, routable endpoints for module integrations
- Check DNS resolution of hostnames before configuring them
- Remember localhost/private IPs are intentionally blocked — don't point modules at in-cluster services
- If self-hosting inference, expose it on an address your SSRF policy allows
When it happens
Trigger: The module client dials a host whose resolved IP is private/loopback/link-local — e.g. baseUrl set to localhost, 127.0.0.1, 10.x, 172.16-31.x, 192.168.x, 169.254.x, or a DNS name resolving to such an address.
Common situations: Local development pointing a vectorizer/generative module at localhost inference server; Kubernetes in-cluster service using cluster-internal IPs (cluster-local traffic blocked); DNS rebinding or misconfigured external hostname resolving to a private IP.
Related errors
- baseURL cannot target internal addresses
- invalid dial address %q: %w
- values are empty
- empty list
- leader not found
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/2aeeae4382f2fb03.
Report an issue: GitHub.