rathole-org/rathole · error
Neither of `[server]` or `[client]` is defined
Error message
Neither of `[server]` or `[client]` is defined
What it means
The TOML config file parsed successfully but defines neither a `[server]` nor a `[client]` section, so there is nothing for rathole to run. `Config::from_str` requires at least one of the two role sections to be present and returns this error otherwise.
Solutions
- Add a `[server]` or `[client]` section to the config file passed to the binary
- Check that the config file you actually passed (-c path) is the role-specific one, not only the shared/common file
- Verify section headers are top-level, correctly spelled lowercase `[server]`/`[client]`, and not indented under another table
Example fix
# before
[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
let cfg = std::fs::read_to_string(path)?;
let raw: toml::Value = toml::from_str(&cfg)?;
if raw.get("server").is_none() && raw.get("client").is_none() {
return Err(format!("{}: config has neither [server] nor [client]", path));
} Prevention
- Always run the binary against a role-specific config, not just the shared/common one
- Keep `[server]`/`[client]` headers top-level and lowercase
- Validate the config with a dry run before deploying
When it happens
Trigger: Calling `Config::from_str` (or running the binary) with a config whose top-level tables are only things like `[transport]`/`[network]` (shared config include), a completely empty file, a config where the sections are misspelled or nested under another table, or a file with only comments.
Common situations: Users split config into a common file plus server/client files and run the binary against only the common file; typos like `[Server]` (case) or accidentally indenting the section so it lands inside another table; pointing `-c` at the wrong file.
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
- Unknown proxy scheme
- Missing TLS configuration
- Missing `pkcs12` or `pkcs12_password`
- The feature ' ' is not compiled in this binary. Please…
- Neither of the feature
AI-assisted analysis of rathole-org/rathole@a292f7ed54 (2026-09-07).
Data as JSON: /api/errors/6629dd9b57bb7eb6.
Report an issue: GitHub.
Appendix: source
Thrown at src/config.rs:252
pub struct Config {
pub server: Option<ServerConfig>,
pub client: Option<ClientConfig>,
}
impl Config {
fn from_str(s: &str) -> Result<Config> {
let mut config: Config = toml::from_str(s).with_context(|| "Failed to parse the config")?;
if let Some(server) = config.server.as_mut() {
Config::validate_server_config(server)?;
}
if let Some(client) = config.client.as_mut() {
Config::validate_client_config(client)?;
}
if config.server.is_none() && config.client.is_none() {
Err(anyhow!("Neither of `[server]` or `[client]` is defined"))
} else {
Ok(config)
}
}
fn validate_server_config(server: &mut ServerConfig) -> Result<()> {
// Validate services
for (name, s) in &mut server.services {
s.name = name.clone();
if s.token.is_none() {
s.token = server.default_token.clone();
if s.token.is_none() {
bail!("The token of service {} is not set", name);
}
}
}
Config::validate_transport_config(&server.transport, true)?;View on GitHub (pinned to a292f7ed54)