PyO3/pyo3 · error

PYO3_CONFIG_FILE must be an absolute path

Error message

PYO3_CONFIG_FILE must be an absolute path

What it means

The PYO3_CONFIG_FILE environment variable lets users supply a hand-written interpreter config. Because the build script runs with a working directory different from where cargo was invoked, a relative path would resolve incorrectly, so pyo3 requires the value to be an absolute path and bails otherwise.

Source

Thrown at pyo3-build-config/src/impl_.rs:668

            .shared(shared || framework)
            .pointer_width(pointer_width)
            .lib_name(lib_name)
            .lib_dir(lib_dir)
            .python_framework_prefix(python_framework_prefix)
            .build_flags(build_flags)
            .finalize()
    }

    /// Import an externally-provided config file.
    ///
    /// The `abi3` features, if set, may apply an `abi3` constraint to the Python version.
    pub(super) fn from_pyo3_config_file_env(target: &Triple) -> Option<Result<Self>> {
        env_var("PYO3_CONFIG_FILE").map(|path| {
            let path = Path::new(&path);
            println!("cargo:rerun-if-changed={}", path.display());
            // Absolute path is necessary because this build script is run with a cwd different to the
            // original `cargo build` instruction.
            ensure!(
                path.is_absolute(),
                "PYO3_CONFIG_FILE must be an absolute path"
            );

            let mut config = InterpreterConfig::from_path(path)
                .context("failed to parse contents of PYO3_CONFIG_FILE")?
                .apply_build_env()?;

            // For config files which don't apply a lib name, apply a default which we can use
            // for linking.
            if config.lib_name.is_none() {
                config.lib_name = Some(default_lib_name_for_target(config.target_abi, target));
            }

            Ok(config)
        })
    }

View on GitHub (pinned to ac9b6899d3)

Solutions

  1. Set PYO3_CONFIG_FILE to an absolute path: `export PYO3_CONFIG_FILE="$PWD/pyo3-config.txt"`
  2. Generate the path in the build wrapper with an absolute resolver (realpath/readlink -f) before exporting
  3. In CI, compute the absolute path from the repo root variable rather than using a relative literal

Example fix

# before
export PYO3_CONFIG_FILE=./pyo3-config.txt
cargo build
# after
export PYO3_CONFIG_FILE="$PWD/pyo3-config.txt"
cargo build
Defensive patterns

Strategy: validation

Validate before calling

// shell
[ -n "$PYO3_CONFIG_FILE" ] && [ "$(readlink -f "$PYO3_CONFIG_FILE")" = "$PYO3_CONFIG_FILE" ] || echo 'PYO3_CONFIG_FILE must be absolute'

Prevention

When it happens

Trigger: Setting PYO3_CONFIG_FILE to a relative path (e.g. PYO3_CONFIG_FILE=./python-config or `interpreter.cfg`) before cargo build; from_pyo3_config_file_env calls path.is_absolute() and ensure! fails on false.

Common situations: Copy-pasting docs examples and forgetting to expand the path; CI scripts using paths relative to the repo root while cargo runs from a workspace member directory; Docker builds with WORKDIR changes.

Related errors


AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05). Data as JSON: /api/errors/7941f04482bb098d. Report an issue: GitHub.