psycopg/psycopg2 · critical · Warning

pg_config --{attr_name} failed: {err}

Error message

pg_config --{attr_name} failed: {err}

What it means

Raised in PostgresConfig.query() (setup.py:117) as a Warning when pg_config ran but returned a non-zero exit code with stderr output. This means the executable exists but the invocation failed - typically a broken/partial PostgreSQL install, a pg_config from a different major version, an architecture mismatch (e.g. 32-bit pg_config driving a 64-bit build), or a wrapper/shim script that errors. finalize_options() catches the Warning, prints 'Error: ...', and exits 1.

Source

Thrown at setup.py:117

<https://www.psycopg.org/docs/install.html>).

""")
            sys.exit(1)

    def query(self, attr_name, *, empty_ok=False):
        """Spawn the pg_config executable, querying for the given config
        name, and return the printed value, sanitized. """
        try:
            pg_config_process = subprocess.run(
                [self.pg_config_exe, "--" + attr_name],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE)
        except OSError:
            raise Warning(
                f"Unable to find 'pg_config' file in '{self.pg_config_exe}'")
        if pg_config_process.returncode:
            err = pg_config_process.stderr.decode(errors='backslashreplace')
            raise Warning(f"pg_config --{attr_name} failed: {err}")
        result = pg_config_process.stdout.decode().strip()
        if not result and not empty_ok:
            raise Warning(f"pg_config --{attr_name} is empty")
        return result

    def find_on_path(self, exename, path_directories=None):
        if not path_directories:
            path_directories = os.environ['PATH'].split(os.pathsep)
        for dir_name in path_directories:
            fullpath = os.path.join(dir_name, exename)
            if os.path.isfile(fullpath):
                return fullpath
        return None

    def autodetect_pg_config_path(self):
        """Find and return the path to the pg_config executable."""
        if PLATFORM_IS_WINDOWS:
            return self.autodetect_pg_config_path_windows()

View on GitHub (pinned to 3a6d9d6ddc)

Solutions

  1. Reinstall or repair the PostgreSQL client dev package so pg_config works cleanly.
  2. Reproduce manually: run '/path/to/pg_config --libdir' (and --includedir) and read the stderr to find the real cause.
  3. Reinstall to a clean PostgreSQL and use psycopg2-binary if you cannot repair the local install.
Defensive patterns

Strategy: validation

Validate before calling

import subprocess, shutil

def pg_config_attr_works(attr: str = 'libdir', path: str | None = None) -> bool:
    p = path or shutil.which('pg_config')
    if not p:
        return False
    res = subprocess.run([p, '--' + attr], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    return res.returncode == 0

assert pg_config_attr_works('libdir') and pg_config_attr_works('includedir')

Try / catch

# Diagnose in CI before building:
#   pg_config --libdir && pg_config --includedir && pg_config --includedir-server
# any non-zero exit means the install is broken - reinstall the Postgres dev package.

Prevention

When it happens

Trigger: Any pg_config_helper.query('libdir'|'includedir'|'includedir-server'|'libdir' for static) during finalize_options() when that pg_config subcommand exits non-zero. The {err} field carries the decoded stderr so you can see the underlying failure.

Common situations: Multiple PostgreSQL installations with a stale pg_config first on PATH; corrupted/incomplete client packages; hand-written pg_config shims in custom images; cross-architecture or cross-version toolchain mismatches.

Related errors


AI-assisted analysis of psycopg/psycopg2@3a6d9d6ddc (2026-08-04). Data as JSON: /data/errors/17e2e58cffbebc2d.json. Report an issue: GitHub.