valeriansaliou/sonic · critical · panic
error reading config
Error message
error reading config
What it means
sonic-server's Config::parse builds a figment/config value from file sources plus SONIC_-prefixed environment variables and calls .expect("error reading config"). This panics when the config crate cannot even load/assemble the raw configuration — before any deserialization — typically because a configured file is missing/unreadable or an environment source is malformed.
Source
Thrown at server/src/config.rs:85
impl Config {
pub fn parse(source: impl ::config::Source + Send + Sync + 'static) -> Self {
// Read configuration.
let raw_config: config::Config = config::Config::builder()
// Start from defaults.
.add_source(config::File::from_str(
defaults_toml(),
config::FileFormat::Toml,
))
// Merge static configuration (from file).
.add_source(source)
// Merge environment overrides.
.add_source(
config::Environment::with_prefix("SONIC")
.separator("__")
.prefix_separator("_"),
)
.build()
.expect("error reading config");
// `#[serde(flatten)]` breaks type coercion from the `config` crate,
// so we can’t have `crate::Config` define
// `#[serde(flatten)] sonic: sonic::Config`. It’s a bit dirty but at
// least we don’t have to manually add custom deserialization logic to
// all non-string fields (in the core!).
#[derive(serde::Deserialize)]
pub struct ServerConfigTemp {
pub channel: ConfigChannel,
pub server: ConfigServer,
}
// Parse configuration.
let mut server_config = raw_config
.clone()
.try_deserialize::<ServerConfigTemp>()
.expect("syntax error in config");
let mut core_config = raw_configView on GitHub (pinned to e6a72da6a5)
Solutions
- Verify the config file path passed to the server exists and is readable
- Check env var naming: prefix SONIC_, nesting separator __ (e.g. SONIC_SERVER__LOG_LEVEL)
- Validate the config file syntax (JSON/YAML/TOML matches the format figment detects by extension)
- Run with a minimal known-good config to isolate which source fails
Example fix
// before SONIC_SERVER_LOG_LEVEL=debug # wrong nesting separator // after SONIC_SERVER__LOG_LEVEL=debug
Defensive patterns
Strategy: validation
Validate before calling
// Rust: pre-flight check before starting the server
let path = std::path::Path::new(&config_path);
if !path.exists() { panic!("config file not found: {}", config_path); }
for (k, _) in std::env::vars().filter(|(k, _)| k.starts_with("SONIC_")) {
// env keys must use SONIC_ prefix and __ nesting separator
} Try / catch
// Run Config::parse in a guarded startup path and print the source error
let conf = std::panic::catch_unwind(Config::parse)
.map_err(|p| format!("config load failed: {:?}", p))?; Prevention
- Always pass an explicit --config path and verify it exists in your launcher script
- Use SONIC_ prefix with __ (double underscore) for nested env overrides
- Keep a known-good example config in the repo and diff against it on failures
- Validate config file syntax with the appropriate linter (TOML/YAML/JSON) in CI
When it happens
Trigger: Calling Config::parse (directly or via Task/PendingTask startup) when the config file passed (or its default location) does not exist, cannot be read, has invalid syntax at the source level, or a SONIC_* env var cannot be merged.
Common situations: Wrong --config path on startup; file permissions; env vars like SONIC_SERVER__LOG_LEVEL with values that break source building; missing config file in container images.
Related errors
- invalid log level
- unable to initialize japanese tokenizer
- syntax error in config
- write_buffer for kv must not be zero
- BrokenPipe
AI-assisted analysis of valeriansaliou/sonic@e6a72da6a5 (2026-09-01).
Data as JSON: /api/errors/39957b1568ddd4ae.
Report an issue: GitHub.