neondatabase/neon · error · anyhow::Error

initdb failed with status {status}

Error message

initdb failed with status {status}

What it means

The storage controller initializes its private postgres cluster by spawning initdb with LD_LIBRARY_PATH/DYLD_LIBRARY_PATH pointing at the built pg lib dir. A non-zero initdb exit is reported bare — initdb's own stderr is not captured into the message.

Source

Thrown at control_plane/src/storage_controller.rs:423

                ];
                tracing::info!(
                    "Initializing storage controller database with args: {:?}",
                    initdb_args
                );

                // Initialize empty database
                let initdb_path = pg_bin_dir.join("initdb");
                let mut child = Command::new(&initdb_path)
                    .envs(vec![
                        ("LD_LIBRARY_PATH".to_owned(), pg_lib_dir.to_string()),
                        ("DYLD_LIBRARY_PATH".to_owned(), pg_lib_dir.to_string()),
                    ])
                    .args(initdb_args)
                    .spawn()
                    .expect("Failed to spawn initdb");
                let status = child.wait().await?;
                if !status.success() {
                    anyhow::bail!("initdb failed with status {status}");
                }
            };

            // Write a minimal config file:
            // - Specify the port, since this is chosen dynamically
            // - Switch off fsync, since we're running on lightweight test environments and when e.g. scale testing
            //   the storage controller we don't want a slow local disk to interfere with that.
            //
            // NB: it's important that we rewrite this file on each start command so we propagate changes
            // from `LocalEnv`'s config file (`.neon/config`).
            tokio::fs::write(
                &pg_data_path.join("postgresql.conf"),
                format!("port = {postgres_port}\nfsync=off\n"),
            )
            .await?;

            println!("Starting storage controller database...");
            let db_start_args = [

View on GitHub (pinned to 8f60b04da4)

Solutions

  1. Run initdb manually with the same args and env against a temp dir to see its real error output
  2. Remove the leftover storage_controller_db directory before re-initializing
  3. Verify <pg_distrib_dir>/v<major>/lib contains the shared libraries
  4. Check disk space and write permissions on base_data_dir
Defensive patterns

Strategy: validation

Validate before calling

let pgdata = env.base_data_dir.join("storage_controller_db");
if pgdata.exists() {
    anyhow::ensure!(
        std::fs::read_dir(&pgdata)?.next().is_none(),
        "pgdata not empty; remove storage_controller_db before re-init"
    );
}

Prevention

When it happens

Trigger: The target pgdata directory (base_data_dir/storage_controller_db) already contains files, initdb cannot load required shared libraries from pg_lib_dir, insufficient disk space, bad permissions, or unsupported locale arguments.

Common situations: Retrying storcon start after a failed first run without cleaning storage_controller_db, a pg build whose libs are not where pg_lib_dir points, read-only or full filesystems.

Related errors


AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16). Data as JSON: /api/errors/a94e593ed0230681. Report an issue: GitHub.