jdx/mise · error

Postgres initialization failed; existing data was preserved

Error message

Postgres initialization failed; existing data was preserved

What it means

initialize stages a fresh data directory and runs `initdb -D <staged> -U postgres --auth=trust`; if initdb exits non-zero, the staged initialization failed. Because staging happens in a temp dir, the existing (old) data directory is untouched and preserved.

Solutions

  1. Ensure initdb (from the postgres tool install) is on PATH and executable
  2. Check initdb's stderr by running it manually on the same parent directory
  3. Free disk space / fix permissions on the state directory
  4. Check locale environment variables (LC_ALL/LANG) that initdb may reject

Example fix

// shell before: initdb not on PATH
PATH="$HOME/.local/share/mise/installs/postgres/16/bin:$PATH" mise daemon start
Defensive patterns

Strategy: retry

Validate before calling

command -v initdb && initdb --version || echo 'initdb missing or broken'

Try / catch

catch (e) { if (/Postgres initialization failed/.test(e.message)) { checkInitdbPathAndLocale(); /* existing data is preserved, safe to retry */ } }

Prevention

When it happens

Trigger: initdb fails during initialization of a new postgres data dir — e.g. initdb not on PATH (command spawn) or exits non-zero due to bad locale/permissions/existing files.

Common situations: initdb binary missing or not executable; insufficient permissions on the staging parent; locale/encoding problems in the environment; disk full.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/d069290f77488f5e. Report an issue: GitHub.

Appendix: source

Thrown at src/daemons/presets.rs:226

                .trim()
                != major
        {
            bail!("Postgres data version does not match its initialization marker");
        }
        return Ok(());
    }
    let staging = tempfile::Builder::new()
        .prefix(".mise-init-")
        .tempdir_in(parent)?;
    let staged_data: PathBuf = staging.path().join("data");
    if preset_name == "postgres" {
        let status = Command::new("initdb")
            .args(["-D"])
            .arg(&staged_data)
            .args(["-U", "postgres", "--auth=trust"])
            .status()?;
        if !status.success() {
            bail!("Postgres initialization failed; existing data was preserved");
        }
        if database != "postgres" {
            if database.is_empty()
                || !database
                    .chars()
                    .all(|c| c.is_ascii_alphanumeric() || c == '_')
            {
                bail!("invalid database name");
            }
            let mut child = Command::new("postgres")
                .arg("--single")
                .arg("-D")
                .arg(&staged_data)
                .arg("postgres")
                .stdin(Stdio::piped())
                .spawn()?;
            writeln!(
                child.stdin.take().unwrap(),

View on GitHub (pinned to 533346cc37)