rathole-org/rathole · critical

Cannot determine running as a server or a client

Error message

Cannot determine running as a server or a client

What it means

run_instance panics when determine_run_mode cannot decide whether rathole should act as a server or a client. The run mode is derived from the config file contents and CLI args, and RunMode::Undetermine means neither was conclusive. Since the process cannot proceed without a mode, it aborts with this panic.

Solutions

  1. Add a [client] or [server] section to the config TOML
  2. Pass an explicit flag: rathole --server config.toml (or --client)
  3. Fix typos in the config section names and re-run
  4. Verify rathole is reading the config file you think it is (check the path argument)

Example fix

// before: config.toml
[transport]
type = "tcp"

// after
[client]
remote_addr = "example.com:2333"

[client.services]
ssh = { local_addr = "127.0.0.1:22" }
Defensive patterns

Strategy: validation

Validate before calling

// Validate the config has exactly one run-mode section before launching:
import re, sys
cfg = open('config.toml').read()
has_server = re.search(r'^\s*\[server\]', cfg, re.M) is not None
has_client = re.search(r'^\s*\[client\]', cfg, re.M) is not None
if has_server == has_client:
    sys.exit('Config must contain exactly one of [server] or [client] (or pass --server/--client)')

Prevention

When it happens

Trigger: Running rathole with a config that has neither a [server] nor a [client] section (or an empty one) and no --server/--client CLI flag to disambiguate.

Common situations: Empty or mistyped config file (e.g. writing [sever] instead of [server]); pointing rathole at the wrong TOML file; passing only the transport section in config.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at src/lib.rs:124

                    let _ = service_update_tx.send(ev).await;
                }
            }
        }
    }

    let _ = shutdown_tx.send(true);

    Ok(())
}

async fn run_instance(
    config: Config,
    args: Cli,
    shutdown_rx: broadcast::Receiver<bool>,
    service_update: mpsc::Receiver<ConfigChange>,
) -> Result<()> {
    match determine_run_mode(&config, &args) {
        RunMode::Undetermine => panic!("Cannot determine running as a server or a client"),
        RunMode::Client => {
            #[cfg(not(feature = "client"))]
            crate::helper::feature_not_compile("client");
            #[cfg(feature = "client")]
            run_client(config, shutdown_rx, service_update).await
        }
        RunMode::Server => {
            #[cfg(not(feature = "server"))]
            crate::helper::feature_not_compile("server");
            #[cfg(feature = "server")]
            run_server(config, shutdown_rx, service_update).await
        }
    }
}

#[derive(PartialEq, Eq, Debug)]
enum RunMode {
    Server,

View on GitHub (pinned to a292f7ed54)