{"record":{"id":"aff8b5204d76945f","repo":"rathole-org/rathole","slug":"the-token-of-service-is-not-set","errorCode":null,"errorMessage":"The token of service {} is not set","messagePattern":"The token of service (.+?) is not set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/config.rs","lineNumber":265,"sourceCode":"        if let Some(client) = config.client.as_mut() {\n            Config::validate_client_config(client)?;\n        }\n\n        if config.server.is_none() && config.client.is_none() {\n            Err(anyhow!(\"Neither of `[server]` or `[client]` is defined\"))\n        } else {\n            Ok(config)\n        }\n    }\n\n    fn validate_server_config(server: &mut ServerConfig) -> Result<()> {\n        // Validate services\n        for (name, s) in &mut server.services {\n            s.name = name.clone();\n            if s.token.is_none() {\n                s.token = server.default_token.clone();\n                if s.token.is_none() {\n                    bail!(\"The token of service {} is not set\", name);\n                }\n            }\n        }\n\n        Config::validate_transport_config(&server.transport, true)?;\n\n        Ok(())\n    }\n\n    fn validate_client_config(client: &mut ClientConfig) -> Result<()> {\n        // Validate services\n        for (name, s) in &mut client.services {\n            s.name = name.clone();\n            if s.token.is_none() {\n                s.token = client.default_token.clone();\n                if s.token.is_none() {\n                    bail!(\"The token of service {} is not set\", name);\n                }","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/rathole-org/rathole/blob/a292f7ed5402f840415fc6a53827da2f34337856/src/config.rs#L247-L283","documentation":"validate_server_config fails when a server-side service has no token and the server has no default_token either. Tokens authenticate clients to services; without one rathole refuses to start rather than run an unauthenticated service. The error names the offending service.","triggerScenarios":"Running rathole in server mode with a [server.services.<name>] entry that lacks a token while [server] also lacks default_token; config validation calls bail! at startup.","commonSituations":"Hand-writing a minimal server.toml and skipping the token; migrating configs and dropping default_token; generating config from templates where the token field was left blank.","solutions":["Set default_token under [server] to cover all services","Add a per-service token in the service's config block","Ensure the client config uses the identical token for the same service"],"exampleFix":"// before\n[server]\nbind_addr = \"0.0.0.0:2333\"\n\n[server.services.ssh]\nbind_addr = \"0.0.0.0:6022\"\n\n// after\n[server]\nbind_addr = \"0.0.0.0:2333\"\ndefault_token = \"secret-token\"\n\n[server.services.ssh]\nbind_addr = \"0.0.0.0:6022\"","handlingStrategy":"validation","validationCode":"// Python pre-check of server config tokens:\nimport tomllib\ncfg = tomllib.load(open('server.toml','rb'))\nsrv = cfg['server']\nfor name, svc in srv.get('services', {}).items():\n    if 'token' not in svc and 'default_token' not in srv:\n        raise SystemExit(f'Service {name} needs a token or server needs default_token')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set default_token at the [server] level as a baseline","Use a config template that includes a token placeholder","Keep tokens in a secret manager and inject them at deploy time"],"tags":["rust","configuration","authentication","token"],"backgroundTag":"missing-required-config-field","analyzedSha":"a292f7ed5402f840415fc6a53827da2f34337856","analyzedAt":"2026-09-07T09:56:55.739Z","contentChangedAt":"2026-09-07T09:56:55.739Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}