linera-io/linera-protocol · critical
Fail to read server config
Error message
Fail to read server config
What it means
The validator proxy's run() loads its ValidatorServerConfig with util::read_json(&self.config_path).expect("Fail to read server config"). The panic fires when the config file cannot be opened or its JSON cannot be deserialized into ValidatorServerConfig, before the proxy starts serving.
Solutions
- Confirm the file exists and is readable at the exact path passed to the proxy (use absolute paths in systemd units)
- Validate the JSON (jq . config.json) and diff its structure against a freshly generated ValidatorServerConfig for your version
- Regenerate the server config with the proxy's generate/setup flow for the current version rather than hand-editing an old file
- Check file permissions/ownership for the service user running the proxy
Example fix
# before linera-proxy --config config.json # relative path, wrong cwd # after jq . /etc/linera/proxy/server.json # valid JSON + schema linera-proxy --config /etc/linera/proxy/server.json
Defensive patterns
Strategy: validation
Validate before calling
# Systemd-style pre-flight for the proxy config. ExecStartPre=/bin/sh -c 'test -r /etc/linera/proxy/server.json && jq -e .validator.public_key /etc/linera/proxy/server.json > /dev/null'
Prevention
- Use absolute config paths in unit files and container commands
- Generate configs with the current version's tooling; do not hand-merge old JSON
- Add a pre-start validation step so failures produce actionable logs instead of a Rust panic
- Mount configs read-only and verify ownership for the service user
When it happens
Trigger: Launching linera-proxy with a --config path that does not exist, is not readable, contains invalid JSON, or has a ValidatorServerConfig schema mismatch (missing validator section, wrong key names for the installed version).
Common situations: First-time proxy deployment where the config was never generated; path typos or running from a different working directory with a relative path; config written for an older/newer Linera version after upgrade; file ownership issues under systemd/container users.
Related errors
- Failed to read server config
- Unable to read committee config file
- Application parameters must be deserializable
- Failed to deserialize query response from application
- Failed to deserialize service response
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/2fb61269df14dc94.
Report an issue: GitHub.
Appendix: source
Thrown at linera-service/src/proxy/main.rs:619
if let Some(threads) = options.tokio_threads {
builder.worker_threads(threads);
}
builder
};
if let Some(blocking_threads) = options.tokio_blocking_threads {
runtime.max_blocking_threads(blocking_threads);
}
runtime.enable_all().build()?.block_on(options.run())
}
impl ProxyOptions {
async fn run(&self) -> Result<()> {
let server_config: ValidatorServerConfig =
util::read_json(&self.config_path).expect("Fail to read server config");
let public_key = &server_config.validator.public_key;
linera_service::tracing::opentelemetry::init(
&format!("validator-{public_key}-proxy"),
self.otlp_exporter_endpoint.as_deref(),
);
let store_config = self
.storage_config
.add_common_storage_options(&self.common_storage_options)?;
let cache_sizes = self.common_storage_options.storage_cache_config();
// Proxies are part of validator infrastructure and should not output contract logs.
let allow_application_logs = false;
store_config
.run_with_storage(
None,
allow_application_logs,
cache_sizes,
ProxyContext::from_options(self)?,View on GitHub (pinned to 6c226ddcb3)