Hmbown/CodeWhale · error

Unauthenticated Runtime access is loopback-only; remove…

Error message

Unauthenticated Runtime access is loopback-only; remove --insecure or bind to 127.0.0.1 or ::1

What it means

Unauthenticated Runtime access (insecure_no_auth) is only permitted on a loopback bind; on any other host the API would be exposed without credentials. This is the catch-all guard for --insecure with a non-loopback host.

Solutions

  1. Remove `--insecure` and configure Runtime authentication
  2. Bind to 127.0.0.1 or ::1 to keep unauthenticated access loopback-only
  3. Audit scripts/containers that inject --host 0.0.0.0 by default

Example fix

// before
codewhale runtime --insecure --host 0.0.0.0
// after
codewhale runtime --insecure --host 127.0.0.1
Defensive patterns

Strategy: validation

Validate before calling

const LOOPBACK: [&str; 2] = ["127.0.0.1", "::1"];
if insecure_flag && !LOOPBACK.contains(&host.as_str()) { return Err("--insecure requires a loopback bind".into()); }

Prevention

When it happens

Trigger: Starting the Runtime API with `--insecure` (and web/mobile checks not already triggering) while `is_loopback_bind_host(&options.host)` is false, e.g. `--host 0.0.0.0` or a LAN address.

Common situations: Disabling auth for convenience in a shared/dev box with a permissive bind host; copying a server config that binds all interfaces while --insecure remains set.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at crates/tui/src/runtime_api.rs:1118

/// overlay transport, so a non-loopback listener would expose the Runtime API
/// to peers that can observe or replay browser traffic.
fn validate_runtime_listener_security(options: &RuntimeApiOptions) -> Result<()> {
    if options.port == 0 {
        bail!("Port must be > 0");
    }
    if options.web && options.host != "127.0.0.1" {
        bail!("Codewhale web is loopback-only and must bind to 127.0.0.1");
    }
    if options.web && options.insecure_no_auth {
        bail!("Codewhale web requires Runtime authentication; remove --insecure");
    }
    if options.mobile && !is_loopback_bind_host(&options.host) {
        bail!(
            "Codewhale mobile is loopback-only without TLS or a verified overlay; bind to 127.0.0.1 or ::1"
        );
    }
    if options.insecure_no_auth && !is_loopback_bind_host(&options.host) {
        bail!(
            "Unauthenticated Runtime access is loopback-only; remove --insecure or bind to 127.0.0.1 or ::1"
        );
    }
    Ok(())
}

fn is_loopback_bind_host(host: &str) -> bool {
    host.parse::<IpAddr>()
        .is_ok_and(|address| address.is_loopback())
}

fn runtime_bind_address(host: &str, port: u16) -> Result<SocketAddr> {
    let address = match host.parse::<IpAddr>() {
        Ok(IpAddr::V6(_)) => format!("[{host}]:{port}"),
        _ => format!("{host}:{port}"),
    };
    address
        .parse()

View on GitHub (pinned to 73e0f67d83)