pypa/pip · error · ConfigurationFileCouldNotBeLoaded
<dynamic: configparser error>
Error message
<dynamic: configparser error>
What it means
Raised when pip's config file parser (configparser.RawConfigParser) hits a structural error while reading a pip config / requirements configuration file (e.g. duplicate options, malformed sections, or missing section headers). It is wrapped in ConfigurationFileCouldNotBeLoaded so the user gets a friendly message naming the offending file rather than a raw configparser traceback. The underlying configparser.Error (DuplicateOptionError, MissingSectionHeaderError, DuplicateSectionError, etc.) is stored in .error.
Source
Thrown at src/pip/_internal/configuration.py:306
def _construct_parser(self, fname: str) -> RawConfigParser:
parser = configparser.RawConfigParser()
# If there is no such file, don't bother reading it but create the
# parser anyway, to hold the data.
# Doing this is useful when modifying and saving files, where we don't
# need to construct a parser.
if os.path.exists(fname):
locale_encoding = get_locale_encoding()
try:
parser.read(fname, encoding=locale_encoding)
except UnicodeDecodeError:
# See https://github.com/pypa/pip/issues/4963
raise ConfigurationFileCouldNotBeLoaded(
reason=f"contains invalid {locale_encoding} characters",
fname=fname,
)
except configparser.Error as error:
# See https://github.com/pypa/pip/issues/4893
raise ConfigurationFileCouldNotBeLoaded(error=error)
return parser
def _load_environment_vars(self) -> None:
"""Loads configuration from environment variables"""
self._config[kinds.ENV_VAR].setdefault(":env:", {})
self._config[kinds.ENV_VAR][":env:"].update(
self._normalized_keys(":env:", self.get_environ_vars())
)
def _normalized_keys(
self, section: str, items: Iterable[tuple[str, Any]]
) -> dict[str, Any]:
"""Normalizes items to construct a dictionary with normalized keys.
This routine is where the names become keys and are made the same
regardless of source - configuration files or environment.
"""
normalized = {}View on GitHub (pinned to d7d0d0a394)
Solutions
- Open the config file named in the error and fix the reported configparser issue (add the missing [section] header, remove the duplicate key, or correct syntax).
- Validate with 'python -m configparser -c "import configparser; c=configparser.ConfigParser(); c.read(\"<file>\")"' or pip config debug to see which file fails.
- If unsure which file is being loaded, run with PIP_CONFIG_FILE set to a known-good file to isolate the source.
- As a temporary workaround, run with --no-input and an explicit --config-file, or --isolated to skip config loading entirely.
Example fix
; before index-url = https://pypi.org/simple [global] trusted-host = pypi.org ; after (section header must come first) [global] index-url = https://pypi.org/simple trusted-host = pypi.org
Defensive patterns
Strategy: try-catch
Validate before calling
import configparser, sys
p = configparser.RawConfigParser()
try:
p.read(path, encoding='utf-8')
except configparser.Error as e:
print(f'config invalid: {e}'); sys.exit(1)
print('config OK') Type guard
def is_valid_config_file(path: str) -> bool:
import configparser
p = configparser.RawConfigParser()
try:
p.read(path, encoding='utf-8')
return True
except configparser.Error:
return False Try / catch
from pip._internal.exceptions import ConfigurationFileCouldNotBeLoaded
try:
configuration.load()
except ConfigurationFileCouldNotBeLoaded as e:
# e.fname, e.reason, e.error (configparser.Error)
log.error('Config %s failed: %s', e.fname, e.reason) Prevention
- Validate pip.conf with 'pip config debug' after edits.
- Keep config files under version control and review diffs.
- Never put option lines before a [section] header.
- Use PIP_CONFIG_FILE pointing at a tested file in CI.
When it happens
Trigger: Hit during configuration loading (Configuration.load() -> _construct_parser) when the file exists but contains INI syntax that configparser rejects: a line before any [section], a duplicate key/section, or an option assignment parser cannot parse. PIP_CONFIG_FILE pointing at a hand-edited file is the most common trigger.
Common situations: Editing pip.conf / pip.ini manually and introducing a typo; copy-pasting a pip config that uses 'key=value' without a leading [global]/[install] section; switching from a requirements.txt-style flat file into pip.conf without adding sections; duplicate 'index-url' / 'find-links' keys under the same section.
Related errors
- Need exactly one file to operate upon (--user, --site, --glo
- Could not determine appropriate file.
- Can not open an editor for a file name containing " {fname}
- Editor Subprocess exited with exit code {e.returncode}
- Got unexpected number of arguments, expected {n}. (example:
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/f98df96fce4ab48a.json.
Report an issue: GitHub.