{"record":{"id":"84fba5c095c3ce75","repo":"pypa/pip","slug":"configuration-file-could-not-be-loaded-n-error-n","errorCode":null,"errorMessage":"Configuration file could not be loaded.\\n{error}\\n","messagePattern":"Configuration file could not be loaded\\.\\\\n(.+?)\\\\n","errorType":"exception","errorClass":"ConfigurationFileCouldNotBeLoaded","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/configuration.py","lineNumber":306,"sourceCode":"    def _construct_parser(self, fname: str) -> RawConfigParser:\n        parser = configparser.RawConfigParser()\n        # If there is no such file, don't bother reading it but create the\n        # parser anyway, to hold the data.\n        # Doing this is useful when modifying and saving files, where we don't\n        # need to construct a parser.\n        if os.path.exists(fname):\n            locale_encoding = get_locale_encoding()\n            try:\n                parser.read(fname, encoding=locale_encoding)\n            except UnicodeDecodeError:\n                # See https://github.com/pypa/pip/issues/4963\n                raise ConfigurationFileCouldNotBeLoaded(\n                    reason=f\"contains invalid {locale_encoding} characters\",\n                    fname=fname,\n                )\n            except configparser.Error as error:\n                # See https://github.com/pypa/pip/issues/4893\n                raise ConfigurationFileCouldNotBeLoaded(error=error)\n        return parser\n\n    def _load_environment_vars(self) -> None:\n        \"\"\"Loads configuration from environment variables\"\"\"\n        self._config[kinds.ENV_VAR].setdefault(\":env:\", {})\n        self._config[kinds.ENV_VAR][\":env:\"].update(\n            self._normalized_keys(\":env:\", self.get_environ_vars())\n        )\n\n    def _normalized_keys(\n        self, section: str, items: Iterable[tuple[str, Any]]\n    ) -> dict[str, Any]:\n        \"\"\"Normalizes items to construct a dictionary with normalized keys.\n\n        This routine is where the names become keys and are made the same\n        regardless of source - configuration files or environment.\n        \"\"\"\n        normalized = {}","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/configuration.py#L288-L324","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Escape literal percent signs by doubling them (`%%`) to avoid configparser interpolation errors.","Use `pip config set` / `pip config edit` instead of manual editing to avoid syntax mistakes.","Run `pip config debug` to see all config files pip reads, then validate each one."],"exampleFix":"# before (no section header)\nindex-url = https://pypi.org/simple\n# after\n[global]\nindex-url = https://pypi.org/simple","handlingStrategy":"validation","validationCode":"import configparser\n\ndef validate_config_syntax(path: str) -> None:\n    p = configparser.RawConfigParser()\n    try:\n        p.read(path)\n    except configparser.Error as e:\n        raise ValueError(f'{path} has invalid INI syntax: {e}') from e\n    if not p.sections():\n        raise ValueError(f'{path} has no [section] header')\n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use `pip config set`/`pip config edit` instead of hand-editing INI files.","Ensure every option sits under a [section] header.","Double any literal % characters to avoid interpolation errors."],"tags":["pip","config","parsing","syntax","ini"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}