neondatabase/neon · error
Supply either config file path or --config=inline-config
Error message
Supply either config file path or --config=inline-config
What it means
endpoint_storage's main() requires exactly one source of configuration: a positional config file path or --config=<inline JSON>. When neither is supplied, it bails with this message before binding its listener. The chosen string is parsed as JSON into Config (parsing failures surface as a separate 'parsing config' context error).
Source
Thrown at endpoint_storage/src/main.rs:61
#[tokio::main]
async fn main() -> anyhow::Result<()> {
logging::init(
logging::LogFormat::Plain,
logging::TracingErrorLayerEnablement::EnableWithRustLogFilter,
logging::Output::Stdout,
)?;
let args = Args::parse();
let config: Config = if let Some(config_path) = args.config_file {
info!("Reading config from {config_path}");
let config = std::fs::read_to_string(config_path)?;
serde_json::from_str(&config).context("parsing config")?
} else if let Some(config) = args.config {
info!("Reading inline config");
serde_json::from_str(&config).context("parsing config")?
} else {
anyhow::bail!("Supply either config file path or --config=inline-config");
};
info!("Reading pemfile from {}", config.pemfile.clone());
let pemfile = std::fs::read(config.pemfile.clone())?;
info!("Loading public key from {}", config.pemfile.clone());
let auth = endpoint_storage::JwtAuth::new(&pemfile)?;
let listener = tokio::net::TcpListener::bind(config.listen).await.unwrap();
info!("listening on {}", listener.local_addr().unwrap());
let storage =
remote_storage::GenericRemoteStorage::from_storage_kind(config.storage_kind).await?;
let cancel = tokio_util::sync::CancellationToken::new();
if !args.no_s3_check_on_startup {
app::check_storage_permissions(&storage, cancel.clone()).await?;
}
let proxy = std::sync::Arc::new(endpoint_storage::Storage {View on GitHub (pinned to 8f60b04da4)
Solutions
- Pass a config file path as the positional argument: endpoint_storage /path/to/config.json
- Or pass inline JSON: endpoint_storage --config='{"pemfile": ..., "listen": ..., "storage_kind": ...}'
- Check the container command/args in the helm chart or unit file to confirm the argument actually reaches the process
Example fix
# before
./endpoint_storage --no-s3-check-on-startup
# after
./endpoint_storage --config='{"pemfile":"/certs/jwt.pem","listen":"0.0.0.0:51243","storage_kind":{"S3":{"bucket_name":"b","bucket_region":"r","prefix_in_bucket":"p"}}}' Defensive patterns
Strategy: validation
Validate before calling
# shell wrapper: refuse to launch without config
if [ -z "$1" ] && [ -z "$ENDPOINT_STORAGE_CONFIG" ]; then
echo "error: supply a config file path or --config=INLINE_JSON" >&2
exit 2
fi
exec ./endpoint_storage "${1:-}" ${ENDPOINT_STORAGE_CONFIG:+--config=$ENDPOINT_STORAGE_CONFIG} Prevention
- Render the config argument in the chart/unit file once and test it with a dry run
- Validate the JSON config in CI (parse it with the same serde types) before deploy
When it happens
Trigger: Launching the endpoint_storage binary with no positional config file argument and no --config flag; passing only unrelated flags like --no-s3-check-on-startup (which itself requires --config).
Common situations: Kubernetes/helm chart misconfiguration dropping the args; running the binary by hand without reading usage; wrappers that quote away or drop the config argument.
Related errors
- pageserver connection information should be provided
- safekeeper connstrings should be provided
- tenant id should be provided
- timeline id should be provided
- shard {shard_index} missing from pageserver_connection_info
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/993cbca96d10116a.
Report an issue: GitHub.