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

  1. Route the request to a normal unicast public address instead
  2. Remove references to link-local (169.254.x), metadata (fd00:ec2::254-style), multicast, or documentation ranges from configuration
  3. 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.