# Can pgrust boot from an existing Postgres 18.3 data directory?

> Discover if pgrust can boot from an existing Postgres 18.3 data directory. Learn about version compatibility and startup requirements for pgrust.

- Repository: [Michael Malis/pgrust](https://github.com/malisper/pgrust)
- Tags: how-to-guide
- Published: 2026-07-13

---

**Yes, pgrust can boot from an existing PostgreSQL 18.3 data directory because it is compiled from the PostgreSQL 18.3 source tree, but it will abort startup if the `PG_VERSION` file indicates any other major version such as 8.3.**

pgrust is a Rust implementation of PostgreSQL that maintains strict binary compatibility with the upstream PostgreSQL 18.3 storage format. When the server initializes, it locates the data directory through the `-D` command-line option or the `PGDATA` environment variable, then validates the `PG_VERSION` file to ensure the on-disk format matches the compiled server version.

## How pgrust locates and validates the data directory

pgrust follows the same startup conventions as upstream PostgreSQL. The server must resolve the path to the database files and enforce version compatibility to prevent data corruption from format mismatches.

### PGDATA configuration sources

The server determines the data directory path by checking the `-D` command-line flag first, then falling back to the `PGDATA` environment variable. This logic is implemented in [`crates/backend/utils/misc/misc_guc/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/misc/misc_guc/src/lib.rs), where the configuration handling code explicitly documents that the data directory is taken from the `-D` option *or* the `PGDATA` environment variable【1†L404-L407】.

```rust
// Configuration parsing in crates/backend/utils/misc/misc_guc/src/lib.rs
let data_dir = match cli_options.get("-D") {
    Some(path) => PathBuf::from(path),
    None => env::var("PGDATA")
        .map(PathBuf::from)
        .expect("PGDATA must be set or -D provided"),
};

```

### The PG_VERSION compatibility check

Once the data directory is identified, pgrust reads the `PG_VERSION` file to verify the major version matches the compiled PostgreSQL 18.x expectation. This check occurs during the initialization sequence in [`crates/backend/main/initdb/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/main/initdb/src/lib.rs). If the version recorded in `PG_VERSION` does not match the server binary—for example, if it contains `8.3` instead of `18.3`—the server aborts immediately with a version mismatch error.

The data directory layout and version validation logic are documented in [`crates/backend/utils/init/init_small/src/globals.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/init/init_small/src/globals.rs), which defines the expected PGDATA structure used during normal server startup.

## Starting pgrust with an existing 18.3 data directory

To boot pgrust from an existing PostgreSQL 18.3 data directory, ensure the `PG_VERSION` file contains the correct version string and pass the directory path using either the environment variable or command-line option.

```bash

# Method 1: Using the PGDATA environment variable

export PGDATA=/var/lib/postgresql/18.3/data
pgrust

# Method 2: Using the -D command-line flag

pgrust -D /var/lib/postgresql/18.3/data

```

If the version matches, pgrust will proceed through the startup sequence, accessing the global catalog and base tables stored in the directory. The backup utilities in [`crates/backend/backup/basebackup/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/backup/basebackup/src/lib.rs) also reference the `$PGDATA/base` subdirectory, confirming that pgrust relies on the standard PostgreSQL directory layout for base backups.

## Version mismatch behavior with older directories

Attempting to start pgrust against a data directory created by PostgreSQL 8.3 will trigger the version-guard logic. The server detects the `PG_VERSION` file contains `8.3`, which does not match the compiled `18.x` expectation, and exits with a fatal error:

```

pgrust: data directory "/path/to/old-data" is not compatible with this server version
Server version: 18.3
Data directory version: 8.3

```

To use an older data directory, you must first migrate the data using standard PostgreSQL upgrade tools (such as `pg_dumpall` or `pg_upgrade`) to create a PostgreSQL 18.3 compatible dump, then restore it into a fresh pgrust data directory created with `initdb`.

## Key source files for PGDATA handling

The following files contain the implementation details for data directory discovery and version validation:

- **[`crates/backend/utils/misc/misc_guc/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/misc/misc_guc/src/lib.rs)** – Parses the `-D` option and `PGDATA` environment variable; defines the configuration logic for data directory location【1†L404-L407】.
- **[`crates/backend/main/initdb/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/main/initdb/src/lib.rs)** – Implements the `initdb` command and version validation logic that checks `PG_VERSION` against the compiled server version.
- **[`crates/backend/utils/init/init_small/src/globals.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/init/init_small/src/globals.rs)** – Documents the PGDATA directory tree structure and global variables used during startup.
- **[`crates/backend/backup/basebackup/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/backup/basebackup/src/lib.rs)** – References `$PGDATA/base` for base backup operations, confirming reliance on the standard PostgreSQL storage layout.

## Summary

- **pgrust can boot from existing PostgreSQL 18.3 data directories** because it is built from the PostgreSQL 18.3 source tree and expects the `PG_VERSION` file to contain `18.x`.
- The data directory path is resolved from the `-D` command-line option or the `PGDATA` environment variable in [`crates/backend/utils/misc/misc_guc/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/misc/misc_guc/src/lib.rs).
- Strict version checking prevents startup against incompatible data directories such as those from PostgreSQL 8.3.
- For incompatible versions, create a fresh data directory using `pgrust initdb` or migrate existing data using PostgreSQL upgrade utilities.

## Frequently Asked Questions

### Can pgrust boot from a PostgreSQL 16 or 17 data directory?

No, pgrust will refuse to start. The server checks the `PG_VERSION` file during initialization and aborts if the major version does not match the compiled 18.x expectation. You must upgrade the data directory to PostgreSQL 18.3 format using `pg_upgrade` or logical replication before switching to pgrust.

### What error message appears when the PG_VERSION file mismatches?

pgrust outputs a fatal error indicating the data directory is incompatible, showing both the server version (18.3) and the data directory version found in `PG_VERSION`. The server exits immediately to prevent potential data corruption from format incompatibilities.

### How do I migrate data from PostgreSQL 8.3 to pgrust?

Since pgrust requires PostgreSQL 18.3 format, you cannot use the 8.3 data directory directly. Use `pg_dumpall` from a PostgreSQL 8.3 client to export the database schema and data, then import the dump into a fresh pgrust instance running `initdb` to create an 18.3 compatible data directory.

### Does pgrust modify the PGDATA directory structure?

pgrust maintains the standard PostgreSQL directory layout defined in [`crates/backend/utils/init/init_small/src/globals.rs`](https://github.com/malisper/pgrust/blob/main/crates/backend/utils/init/init_small/src/globals.rs) and does not modify the structure of an existing compatible data directory. It writes to standard subdirectories such as `base`, `global`, and `pg_wal` using the same file naming conventions as PostgreSQL 18.3.