PostgreSQL raises ERROR: could not open file "<path>": No such file or directory with SQLSTATE 58P01 and condition name undefined_file when the server attempts to open a file that does not exist at the expected location. This is a system-level I/O error, not a SQL-logic error, meaning it originates from the operating system rather than from the query itself.
What This Error Means
SQLSTATE 58P01 belongs to PostgreSQL error class 58 — "System Error (errors external to PostgreSQL itself)." Class 58 errors indicate that something went wrong at the OS or filesystem level, outside of PostgreSQL's own SQL processing. The P in 58P01 marks it as a PostgreSQL-specific extension to the SQL standard class 58.
When PostgreSQL raises undefined_file, it has attempted a low-level open() or equivalent system call on a file path and received ENOENT (no such file or directory) back from the OS. This can happen during server startup, when loading a shared library extension, when executing a LOAD command, or when certain built-in functions try to read files from the data directory.
Unlike errors in class 22 (data exceptions) or 23 (integrity constraint violations), a class 58 error does not leave the current transaction in an aborted state by itself — but it will typically abort the current statement. The session remains usable unless the error occurs during a critical phase of server startup, in which case PostgreSQL will refuse to start or will shut down.
Common Causes
Missing or uninstalled shared library for an extension. Running
CREATE EXTENSIONorLOADfor an extension (e.g.,pg_stat_statements,postgis,pgvector) when the corresponding.sofile is not present in$libdir(usually/usr/lib/postgresql/<version>/lib/). This is the most common cause.Extension installed for a different PostgreSQL major version. The
.sofile exists but was compiled for a different major version. PostgreSQL looks for version-specific paths and will fail to find the correct file.Manual
LOADof a nonexistent library path. ExecutingLOAD 'some_library'with a path that resolves to a missing file, either because the library was never installed or was removed.shared_preload_librariesreferences a missing library. A library name listed inpostgresql.confundershared_preload_librariesis not present on the filesystem. This causes PostgreSQL to fail at startup with this error.Incorrect
$libdirordynamic_library_pathconfiguration. The library exists but is installed in a non-standard path not covered bydynamic_library_path, so PostgreSQL cannot locate it.File permissions or SELinux/AppArmor denial logged as a missing file. On some OS configurations, a permission denial on the
.sofile may surface as "No such file or directory" at the PostgreSQL level.
How to Fix undefined_file
Install the missing extension package. For system-packaged PostgreSQL, the extension's
.sofile is usually in a separate OS package:# Debian/Ubuntu sudo apt-get install postgresql-<version>-<extension-name> # RHEL/Rocky/Alma sudo dnf install postgresql<version>-<extension-name>After installing, retry
CREATE EXTENSIONorLOADwithout restarting PostgreSQL (for most extensions).Verify the library is in the right location. PostgreSQL's
pg_config --pkglibdirtells you where it expects.sofiles:pg_config --pkglibdir # e.g. /usr/lib/postgresql/16/lib ls /usr/lib/postgresql/16/lib/pg_stat_statements.soIf the file is present but in a different directory, either move it or add that directory to
dynamic_library_pathinpostgresql.conf.Fix
shared_preload_librariesbefore restarting. If the error occurs at startup, editpostgresql.confand remove or correct the offending library name, then start PostgreSQL:-- Check what is currently configured (from a running instance) SHOW shared_preload_libraries;# Edit postgresql.conf and comment out or correct the bad entry sudo nano /etc/postgresql/16/main/postgresql.conf # shared_preload_libraries = 'pg_stat_statements' -- remove the missing one sudo systemctl start postgresqlExtend
dynamic_library_pathto cover a non-standard install location. Inpostgresql.conf:dynamic_library_path = '$libdir:/opt/custom_extensions'Reload the configuration with
SELECT pg_reload_conf();orpg_ctl reload.Check file permissions. Ensure the PostgreSQL process user (typically
postgres) has read and execute permission on the.sofile:ls -la /path/to/library.so sudo chmod 755 /path/to/library.so sudo chown root:root /path/to/library.so
Additional Information
- SQLSTATE class
58contains only a handful of conditions. The sibling codes most commonly encountered are58000(system_error, a generic I/O failure) and58030(io_error, raised for read/write failures on existing files).58P01is specifically for missing files. - This error is distinct from
42883(undefined_function) or42704(undefined_object) — those are SQL-catalog lookup failures, not filesystem errors. - Client drivers (libpq, psycopg, JDBC, node-postgres) surface this as a server-side error with
sqlstate = "58P01". Because it is a server error, it is raised before any query results are returned, and the driver's normal error-handling path applies. - On Docker or Kubernetes deployments, this error frequently appears when an extension is installed in a custom image layer but the production image was not rebuilt, or when a volume mount shadows the directory containing extension libraries.
- PostgreSQL versions 14 and later produce more detailed error messages for some
58P01cases, including the full resolved path that was attempted.
Frequently Asked Questions
Why does PostgreSQL say the file is missing when I can see it on disk?
The most common reasons are: the file is owned or permissioned such that the postgres OS user cannot read it; SELinux or AppArmor is denying access and the kernel reports it as ENOENT; or the file exists in a path not searched by dynamic_library_path. Run ls -la on the file and check dynamic_library_path with SHOW dynamic_library_path;.
Can I get 58P01 from a regular SQL query, not just extension loading?
Rarely, but yes. A few built-in functions read files directly — for example, pg_read_file() will raise 58P01 if the requested file does not exist. Custom functions written in PL/Python, PL/Perl, or C that perform file I/O can also trigger it.
Does 58P01 abort my transaction?
The statement that caused the error is aborted. If you were inside a transaction block, the transaction enters the aborted state and you must issue ROLLBACK before issuing new commands. The session itself remains open unless the error occurred during server startup.
How do I find which library is causing a startup failure?
Check the PostgreSQL server log — the 58P01 message includes the filename that could not be opened. On Linux, the default log location is /var/log/postgresql/ or accessible via journalctl -u postgresql. The message will look like: FATAL: could not load library "/usr/lib/postgresql/16/lib/missing_ext.so": No such file or directory.