rathole-org/rathole · error

Neither of the feature

Error message

Neither of the feature '{}' or '{}' is compiled in this binary. Please re-compile rathole

What it means

Variant of feature_not_compile: fires when code requires at least one of two features (commonly "client" OR "server") but neither was compiled into the binary. It panics because the requested functionality does not exist in this build. This is a build-configuration problem, not a runtime bug.

Solutions

  1. Rebuild with at least one mode feature: cargo build --release --features client (or server, or client,server)
  2. Install the default build: cargo install rathole (includes client and server)
  3. Verify the built binary's features match the mode you run it in

Example fix

// before
cargo build --release --no-default-features --features tls
// running rathole panics: neither client nor server compiled

// after
cargo build --release --no-default-features --features tls,client,server
Defensive patterns

Strategy: validation

Validate before calling

// Ensure at least one of the mode features is enabled at build time:
// In a build.rs or CI check:
// let feats = std::env::var("CARGO_FEATURE_CLIENT").is_ok() || std::env::var("CARGO_FEATURE_SERVER").is_ok();
// assert!(feats, "build must enable client or server");

Prevention

When it happens

Trigger: Invoking a code path guarded by #[cfg(not(feature = "f1"))] #[cfg(not(feature = "f2"))] that calls feature_neither_compile — e.g. running the binary without either the client or server feature enabled.

Common situations: Building with --no-default-features and forgetting to add client or server; producing a transport-only or test build and then trying to run it as a proxy.

Related errors


AI-assisted analysis of rathole-org/rathole@a292f7ed54 (2026-09-07). Data as JSON: /api/errors/89939b9612a38e14. Report an issue: GitHub.

Appendix: source

Thrown at src/helper.rs:48

        "Set TCP keepalive {:?} {:?}",
        keepalive_duration,
        keepalive_interval
    );

    Ok(s.set_tcp_keepalive(&keepalive)?)
}

#[allow(dead_code)]
pub fn feature_not_compile(feature: &str) -> ! {
    panic!(
        "The feature '{}' is not compiled in this binary. Please re-compile rathole",
        feature
    )
}

#[allow(dead_code)]
pub fn feature_neither_compile(feature1: &str, feature2: &str) -> ! {
    panic!(
        "Neither of the feature '{}' or '{}' is compiled in this binary. Please re-compile rathole",
        feature1, feature2
    )
}

pub async fn to_socket_addr<A: ToSocketAddrs>(addr: A) -> Result<SocketAddr> {
    lookup_host(addr)
        .await?
        .next()
        .ok_or_else(|| anyhow!("Failed to lookup the host"))
}

pub fn host_port_pair(s: &str) -> Result<(&str, u16)> {
    let semi = s.rfind(':').expect("missing semicolon");
    Ok((&s[..semi], s[semi + 1..].parse()?))
}

/// Create a UDP socket and connect to `addr`

View on GitHub (pinned to a292f7ed54)