Hmbown/CodeWhale · error
outbound origin must not target a loopback, private, or…
Error message
outbound origin must not target a loopback, private, or reserved address
What it means
If the host parses as an IP address, the validator blocks loopback, private, link-local, unspecified, broadcast, multicast, documentation ranges, carrier-grade NAT (100.64.0.0/10), and their IPv6/IPv4-mapped equivalents. This prevents credential-bearing requests from being aimed at internal network addresses (SSRF).
Solutions
- Give the service a public https hostname and configure that instead of the raw internal IP.
- Route through a reverse proxy on a public address.
- For local development, use a debug build with localhost/127.0.0.1, which has its own explicit path.
Example fix
// before export DAYTONA_API_URL=http://192.168.1.10:8080 // after export DAYTONA_API_URL=https://sandbox.example.com
Defensive patterns
Strategy: validation
Validate before calling
if let Ok(ip) = host.trim_end_matches('.').parse::<std::net::IpAddr>() {
let private = match ip { IpAddr::V4(v4) => v4.is_private() || v4.is_loopback() || v4.is_link_local(), IpAddr::V6(v6) => v6.is_loopback() || (v6.segments()[0] & 0xfe00) == 0xfc00 || (v6.segments()[0] & 0xffc0) == 0xfe80 };
if private { return Err("origin must be a public IP/host"); }
} Try / catch
if let Err(e) = validate_outbound_origin(raw) {
if e.to_string().contains("loopback, private, or reserved") {
eprintln!("origin targets a non-public address (SSRF guard): {raw}");
}
} Prevention
- Use hostnames backed by public DNS instead of raw internal IPs.
- Never configure cloud-metadata or LAN addresses as outbound origins.
- Validate endpoints at startup, before any credential-bearing call.
When it happens
Trigger: Configuring an origin whose host is a raw IP like 192.168.1.10, 10.0.0.5, 169.254.169.254 (metadata service), ::1, or fd00::1.
Common situations: Self-hosted sandbox service on a LAN addressed by IP; attempting to hit a cloud metadata endpoint; IPv6 private addresses in config.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- reviewed plugin MCP endpoint has an unsafe origin
- append_allow_rules only accepts action = "allow"
- Codewhale credentials directory has an unsupported component
- Codewhale terminal receipt exceeded its string bound
- CodewhalePet/1
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/8fd1d66666f907ff.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/cloud_dispatch.rs:1326
v4.is_loopback()
|| v4.is_private()
|| v4.is_link_local()
|| v4.is_unspecified()
|| v4.is_broadcast()
|| v4.is_multicast()
|| v4.is_documentation()
|| (octets[0] == 100 && (octets[1] & 0b1100_0000) == 0b0100_0000)
} else {
v6.is_loopback()
|| v6.is_unspecified()
|| v6.is_multicast()
|| (v6.segments()[0] & 0xfe00) == 0xfc00
|| (v6.segments()[0] & 0xffc0) == 0xfe80
}
}
};
if blocked {
bail!("outbound origin must not target a loopback, private, or reserved address");
}
}
if url.scheme() != "https" {
bail!("outbound origin must use https");
}
Ok(url)
}
/// Meter one closed interval on a dispatched cloud job.
///
/// The job's sandbox id must match the provider observation. Wall-clock after
/// create is not enough: the observation has to be provider-accepted active
/// time bound to the immutable admission.
pub fn meter_cloud_job(
job: &CloudJob,
admission: &ComputerAdmission,
observation: ProviderObservation,
) -> Result<ComputerMeterReceipt, ComputerMeterError> {View on GitHub (pinned to 73e0f67d83)