NationalSecurityAgency/ghidra · error · IOException

Error initializing postgres database

Error message

Error initializing postgres database

What it means

Thrown by initializeDataDirectory() when `pg_ctl init` (PostgreSQL cluster initialization) returns a non-zero exit code. This means PostgreSQL itself refused to initialize the data directory — BSim only reports the aggregate failure, not the postgres detail.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java:909

		command.add("-o");
		command.add("'--username=" + connectingUserName + '\'');
		if (hostAuthentication == AUTHENTICATION_PASSWORD) {
			establishAdminPassword();
			command.add("-o");
			command.add("'--pwfile=" + passwordFile.getAbsolutePath() + '\'');
		}
		else if (hostAuthentication == AUTHENTICATION_PKI) {
			if (commonName == null) {
				throw new GeneralSecurityException(
					"Distinguished name option (--dn) required for " + connectingUserName);
			}
			checkCertAuthorityFile();
		}
		command.add("-D");
		command.add(dataDirectory.getAbsolutePath());
		int res = runCommand(null, command, loadLibraryVar, loadLibraryValue);
		if (res != 0) {
			throw new IOException("Error initializing postgres database");
		}
		File configCopy = new File(dataDirectory, POSTGRES_CONFIGFILE + ".orig");

		if (hostAuthentication == AUTHENTICATION_PKI || localAuthentication == AUTHENTICATION_PKI) {
			File rootCA = new File(dataDirectory, POSTGRES_ROOTCA);
			FileUtilities.copyFile(certAuthorityFile, rootCA, false, null);
			addCertificateName(connectingUserName);
		}

		// Move the original configuration file
		if (!configFile.renameTo(configCopy)) {
			throw new IOException("Error copying original configuration file");
		}

		File hbaCopy = new File(dataDirectory, POSTGRES_CONNECTFILE + ".orig");

		// Move the original connection file
		if (!hbaFile.renameTo(hbaCopy)) {

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Read the postgres log/stderr from the runCommand output to get the real reason.
  2. Point at an empty or freshly-created data directory for a first-time init.
  3. Ensure the OS user running bsim_ctl owns and can write the data directory.
  4. Verify the postgres installation discovered by discoverPostgresInstall() and that loadLibraryVar/loadLibraryValue resolve the shared libraries.
  5. If the directory is already initialized, do not re-init — start directly.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: ensure a clean, writable, empty cluster dir before init.
File d = new File(dataDir);
if (d.exists() && d.list().length > 0) {
    throw new IllegalStateException(
        "Data directory not empty; pg_ctl init will likely fail: " + d);
}

Type guard

public boolean isInitableClusterDir(File d) {
    return d != null && d.isDirectory() && d.canWrite()
        && (d.list() == null || d.list().length == 0);
}

Try / catch

try {
    bsimControl.start(args);
} catch (IOException e) {
    if ("Error initializing postgres database".equals(e.getMessage())) {
        // capture <dataDir>/log output and surface it; do NOT silently retry.
        throw new UserFacingException("pg_ctl init failed; see data dir log", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: The constructed `pg_ctl init -o '--username=...' [-o '--pwfile=...'] -D <dataDir>` command exits non-zero. Common when the data directory is non-empty, lacks permissions, or the postgres binaries/version are wrong.

Common situations: Re-running `bsim_ctl start` against a data directory that was already initialized; data directory owned by another user / not writable; mismatched postgres major version vs existing cluster files; missing LD_LIBRARY_PATH pointing at postgres shared libs (loadLibraryVar); leftover files from a failed prior init.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/0cb894d11aad6d26. Report an issue: GitHub.