Hmbown/CodeWhale · error

loopback origins are not allowed in release builds

Error message

loopback origins are not allowed in release builds

What it means

Loopback hostnames (localhost, 127.0.0.1, ::1) are an explicit escape hatch allowed only in debug builds for local smoke tests against a self-hosted sandbox service. Release builds reject them outright, since production calls must target a real remote service.

Solutions

  1. Point the origin at the real public https endpoint for your environment.
  2. Reproduce the scenario with a debug build (cargo run/dev profile), which permits loopback.
  3. If you genuinely need loopback in release, adjust configuration so the loopback service is reached by other means — there is no flag to bypass this.

Example fix

// before
export DAYTONA_API_URL=http://localhost:3000
// after (release)
export DAYTONA_API_URL=https://api.daytona.example.com
Defensive patterns

Strategy: validation

Validate before calling

let host = reqwest::Url::parse(raw.trim()).ok().and_then(|u| u.host_str().map(str::to_string)).unwrap_or_default();
let loopback = matches!(host.to_ascii_lowercase().as_str(), "localhost" | "127.0.0.1" | "::1");
if loopback && cfg!(not(debug_assertions)) { return Err("loopback origin not allowed in release"); }

Try / catch

match validate_outbound_origin(raw) {
    Err(e) if e.to_string().contains("loopback origins are not allowed") => eprintln!("configured a dev-only localhost origin; point at the public endpoint"),
    other => other?,
}

Prevention

When it happens

Trigger: Running a release build with DAYTONA_API_URL (or toolbox_url) pointing at localhost/127.0.0.1/::1, e.g. a leftover dev configuration promoted to a packaged binary.

Common situations: Shipping a release binary while a local dev endpoint is still configured; CI running release binaries against a local emulator.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/df032adb87ed8179. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/cloud_dispatch.rs:1285

        bail!("outbound origin must not embed credentials");
    }
    let host = url
        .host_str()
        .context("outbound origin has no host")?
        .trim_end_matches('.')
        .to_ascii_lowercase();
    // `Url::host_str` keeps IPv6 brackets; strip them for the checks below.
    let host = host
        .strip_prefix('[')
        .and_then(|inner| inner.strip_suffix(']'))
        .map(str::to_string)
        .unwrap_or(host);
    let loopback_name = host == "localhost" || host == "127.0.0.1" || host == "::1";
    if loopback_name {
        if cfg!(debug_assertions) {
            return Ok(url);
        }
        bail!("loopback origins are not allowed in release builds");
    }
    if host.ends_with(".local") || host.ends_with(".internal") {
        bail!("outbound origin must be a public service host");
    }
    if let Ok(ip) = host.parse::<std::net::IpAddr>() {
        let blocked = match ip {
            std::net::IpAddr::V4(v4) => {
                let octets = v4.octets();
                v4.is_loopback()
                    || v4.is_private()
                    || v4.is_link_local()
                    || v4.is_unspecified()
                    || v4.is_broadcast()
                    || v4.is_multicast()
                    || v4.is_documentation()
                    // 100.64.0.0/10 (carrier-grade NAT, `is_shared` is
                    // not stable yet)
                    || (octets[0] == 100 && (octets[1] & 0b1100_0000) == 0b0100_0000)

View on GitHub (pinned to 73e0f67d83)