JuliusBrussee/caveman · error
ssrf: destination %s (for host %q) is in blocked range %s
Error message
ssrf: destination %s (for host %q) is in blocked range %s
What it means
checkAddr rejected the destination because it falls in an absolutely blocked range (link-local/metadata, ULA outside the local-TUN exception, multicast, unspecified, or documentation prefixes). Unlike loopback and RFC1918, these ranges have no allowlist escape in any mode.
Source
Thrown at shared/platform/ssrf/ssrf.go:287
// Managed mode blocks loopback absolutely — allowing tenants to
// route through 127.x or ::1 would trivially reach local-only
// services. Self-hosted mode opts back in only via an explicit
// allowlist entry: the original host, the IP literal, or
// "localhost" (dial time only ever sees the resolved IP).
if !cfg.ManagedMode &&
(isInAllowList(host, port, cfg.AllowList) || isInAllowList(addr.String(), port, cfg.AllowList) || isInAllowList("localhost", port, cfg.AllowList)) {
return nil
}
// A fail-closed guard that does not name its own escape hatch reads
// as "unsupported" rather than "not opted in" — #841 concluded the
// proxy simply could not reach a local relay, when self-hosted mode
// has allowed exactly that all along. Managed mode is deliberately
// silent: the allowlist is a no-op there by contract, so advertising
// it would send the operator after a setting that cannot help.
if !cfg.ManagedMode {
return fmt.Errorf("ssrf: destination %s (for host %q) is in blocked range %s; add %s to the SSRF allowlist (CAVE_SSRF_ALLOWLIST) to permit it", addr, host, p, allowListSuggestion(addr, port))
}
return fmt.Errorf("ssrf: destination %s (for host %q) is in blocked range %s", addr, host, p)
}
}
for _, p := range selfHostedSyntheticPrefixes {
if p.Contains(addr) {
if !cfg.ManagedMode {
return nil
}
return fmt.Errorf("ssrf: destination %s (for host %q) is in blocked range %s", addr, host, p)
}
}
for _, p := range blockedPrefixes {
if p.Contains(addr) {
// These ranges (link-local/metadata, ULA outside the narrow local-TUN
// exception, multicast, unspecified, documentation) are absolutely
// blocked — no allowlist escape in any mode.
return fmt.Errorf("ssrf: destination %s (for host %q) is in blocked range %s", addr, host, p)View on GitHub (pinned to 766dce6b13)
Solutions
- Route the request to a normal unicast public address instead
- Remove references to link-local (169.254.x), metadata (fd00:ec2::254-style), multicast, or documentation ranges from configuration
- If a local TUN setup is involved, confirm the destination fits the narrow ULA exception already encoded in the policy
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at shared/platform/ssrf/ssrf.go:287 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18).
Data as JSON: /api/errors/cba88bb0b65dc185.
Report an issue: GitHub.