pypa/pip · error · ConfigurationFileCouldNotBeLoaded

Configuration file could not be loaded.\n{error}\n

Error message

Configuration file could not be loaded.\n{error}\n

What it means

Raised by Configuration._construct_parser() when configparser raises a generic Error while reading the config file. This covers INI syntax problems: duplicate sections, duplicate options within a section, malformed lines, missing section headers, or bad interpolation. The underlying configparser error detail is appended.

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 f399c37189)

Solutions

  1. Open the file named in the error and fix the syntax: ensure all options are under a [section] header and there are no duplicate sections/options.
  2. Escape literal percent signs by doubling them (`%%`) to avoid configparser interpolation errors.
  3. Use `pip config set` / `pip config edit` instead of manual editing to avoid syntax mistakes.
  4. Run `pip config debug` to see all config files pip reads, then validate each one.

Example fix

# before (no section header)
index-url = https://pypi.org/simple
# after
[global]
index-url = https://pypi.org/simple
Defensive patterns

Strategy: validation

Validate before calling

import configparser

def validate_config_syntax(path: str) -> None:
    p = configparser.RawConfigParser()
    try:
        p.read(path)
    except configparser.Error as e:
        raise ValueError(f'{path} has invalid INI syntax: {e}') from e
    if not p.sections():
        raise ValueError(f'{path} has no [section] header')

Prevention

When it happens

Trigger: A pip.conf missing the required [section] header; duplicate [global] sections; a line like `key = value` outside any section; a value containing unescaped `%` triggering interpolation errors; tabs vs spaces or stray characters.

Common situations: Hand-editing pip.conf and forgetting the section header; merging config snippets that create duplicate sections; copy-pasting a value with `%` signs (configparser tries interpolation); corrupt or truncated config files.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/84fba5c095c3ce75. Report an issue: GitHub.