PyO3/pyo3 · error
Invalid config that sets both target_abi and abi3.
Error message
Invalid config that sets both target_abi and abi3.
What it means
A PYO3_CONFIG_FILE may specify the ABI either via the legacy `abi3` flag or the newer `target_abi` field, but not both. from_reader rejects a config that sets both to avoid ambiguity about which ABI actually applies.
Source
Thrown at pyo3-build-config/src/impl_.rs:779
parse_value!(suppress_build_script_link_lines, value)
}
"extra_build_script_line" => {
extra_build_script_lines.push(value.to_string());
}
"python_framework_prefix" => parse_value!(python_framework_prefix, value),
unknown => warn!("unknown config key `{}`", unknown),
}
}
let version = version.ok_or("missing value for version")?;
let implementation = implementation.unwrap_or(PythonImplementation::CPython);
let flags_contains_free_threaded = if let Some(ref flags) = build_flags {
flags.0.contains(&BuildFlag::Py_GIL_DISABLED)
} else {
false
};
let target_abi = if let Some(target_abi) = target_abi {
ensure!(
abi3.is_none(),
"Invalid config that sets both target_abi and abi3."
);
target_abi
} else if flags_contains_free_threaded {
// This fires even if is_abi3() is True for backward compatibility reasons
PythonAbiBuilder::new(implementation, version)
.free_threaded()
.finalize()?
} else if abi3 == Some(true) {
warn!("abi3 configuration file option is deprecated since pyo3 0.29, set target_abi instead");
PythonAbiBuilder::new(implementation, version)
.stable_abi(StableAbi::Abi3)
.finalize()?
} else {
PythonAbiBuilder::new(implementation, version).finalize()?
};
View on GitHub (pinned to ac9b6899d3)
Solutions
- Edit the config file and remove the `abi3` line, keeping `target_abi` (or vice versa)
- Regenerate the config file with the pyo3 tooling for your pyo3 version instead of hand-editing
- Verify with `python -m pyo3_build_config`-style tooling or the pyo3 docs which format your pyo3 version expects
Example fix
# pyo3-config.txt, before abi3 target_abi=abi3-cp312 # after target_abi=abi3-cp312
Defensive patterns
Strategy: validation
Validate before calling
// shell grep -q '^abi3' "$PYO3_CONFIG_FILE" && grep -q '^target_abi' "$PYO3_CONFIG_FILE" && echo 'config sets both abi3 and target_abi — remove one'
Prevention
- Use only the current-format target_abi field in hand-written configs
- Regenerate configs with pyo3 tooling rather than merging old and new formats
- Validate custom config files after every pyo3 upgrade
When it happens
Trigger: Hand-editing or tool-generating a pyo3 config file that contains both an `abi3` line and a `target_abi` line; merging config snippets or upgrading a config file from an older pyo3 format by adding target_abi without removing abi3.
Common situations: Manually migrating a config written for old pyo3 to the new format; copy-pasting example config files and combining sections; build tooling that appends target_abi unconditionally to a template that already contains abi3.
Related errors
- Neither abi3 or abi3t features are enabled
- Cannot target an abi3t version below {MINIMUM_SUPPORTED_VERS
- cannot set a minimum Python version {} higher than the inter
- failed to run the Python interpreter at {}: {}
- Python script failed
AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05).
Data as JSON: /api/errors/754e344f8c00b221.
Report an issue: GitHub.