pypa/pip · error · ConfigurationFileCouldNotBeLoaded

contains invalid {locale_encoding} characters

Error message

contains invalid {locale_encoding} characters

What it means

Raised as ConfigurationFileCouldNotBeLoaded in Configuration._construct_parser() at configuration.py:296-303 when parser.read(fname, encoding=locale_encoding) raises UnicodeDecodeError. The config file contains bytes that are invalid under the detected locale encoding, so pip cannot safely parse it. The message reports the encoding that was in effect.

Source

Thrown at src/pip/_internal/configuration.py:300

            items = parser.items(section)
            self._config[variant].setdefault(fname, {})
            self._config[variant][fname].update(self._normalized_keys(section, items))

        return parser

    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]:

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Re-save the config file as UTF-8 (the most portable choice): 'iconv -f UTF-16 -t UTF-8 pip.conf > pip.conf.utf8'.
  2. Remove non-ASCII characters from the config file if they are not essential.
  3. Set a UTF-8 locale in your shell (export LANG=en_US.UTF-8) and retry.
  4. On Windows, re-save pip.ini with explicit UTF-8 encoding (e.g. Set-Content -Encoding utf8).

Example fix

# before — pip.ini saved as UTF-16 by PowerShell
# fix encoding
iconv -f UTF-16 -t UTF-8 ~/.pip/pip.ini > /tmp/pip.conf && mv /tmp/pip.conf ~/.pip/pip.ini
Defensive patterns

Strategy: validation

Validate before calling

import os

def config_file_is_utf8(path: str) -> bool:
    if not os.path.exists(path):
        return True
    with open(path, 'rb') as f:
        data = f.read()
    try:
        data.decode('utf-8')
        return True
    except UnicodeDecodeError:
        return False

if not config_file_is_utf8(os.path.expanduser('~/.pip/pip.conf')):
    print('ERROR: config file is not valid UTF-8; re-save as UTF-8', flush=True)

Type guard

def is_valid_utf8_file(path: str) -> bool:
    try:
        with open(path, 'rb') as f:
            f.read().decode('utf-8')
        return True
    except (UnicodeDecodeError, OSError):
        return False

Try / catch

from pip._internal.exceptions import ConfigurationFileCouldNotBeLoaded
try:
    cfg.load()
except ConfigurationFileCouldNotBeLoaded as e:
    if 'invalid' in str(e) and 'characters' in str(e):
        # re-encode the offending file to UTF-8 and retry
        import subprocess
        subprocess.run(['iconv','-f','UTF-16','-t','UTF-8', e.fname, '-o', e.fname])
        cfg.load()

Prevention

When it happens

Trigger: A pip.conf/pip.ini file saved in an encoding incompatible with the system locale (e.g. UTF-16, or containing bytes outside the locale charset) being read at configuration.py:297. The UnicodeDecodeError is caught and re-raised as a structured ConfigurationFileCouldNotBeLoaded with the locale encoding named.

Common situations: On Windows a pip.ini saved as UTF-16 by PowerShell's Out-File; a config file edited on a different OS with a different charset; non-ASCII characters (e.g. in a URL or comment) saved in a charset the running locale does not cover; LANG/LC_ALL unset causing a narrow locale like ASCII.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/32dea24e3ace4700.json. Report an issue: GitHub.