{"record":{"id":"0788389da16e8e24","repo":"pypa/pip","slug":"keyring-util-is-outdated-must-be-at-least-version","errorCode":null,"errorMessage":"Keyring util is outdated; must be at least version 25.2.1, please upgrade it","messagePattern":"Keyring util is outdated; must be at least version 25\\.2\\.1, please upgrade it","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/network/auth.py","lineNumber":154,"sourceCode":"        env = os.environ.copy()\n        env[\"PYTHONIOENCODING\"] = \"utf-8\"\n        res = subprocess.run(  # noqa: UP022\n            cmd,\n            stdin=subprocess.DEVNULL,\n            stdout=subprocess.PIPE,\n            stderr=subprocess.PIPE,\n            env=env,\n        )\n\n        # Detect if the user is running an outdated version of keyring without support\n        # for querying credentials without username\n        errs = res.stderr.decode(\"utf-8\")\n        if (\n            res.returncode == 2\n            and \"unrecognized arguments\" in errs\n            and \"--mode=creds\" in errs\n        ):\n            raise RuntimeError(\n                \"Keyring util is outdated; must be at least version 25.2.1, \"\n                \"please upgrade it\"\n            )\n\n        if res.returncode:\n            return None\n\n        data = json.loads(res.stdout.decode(\"utf-8\"))\n        return (data[\"username\"], data[\"password\"])\n\n    def _set_password(self, service_name: str, username: str, password: str) -> None:\n        \"\"\"Mirror the implementation of keyring.set_password using cli\"\"\"\n        if self.keyring is None:\n            return None\n        env = os.environ.copy()\n        env[\"PYTHONIOENCODING\"] = \"utf-8\"\n        subprocess.run(\n            [self.keyring, \"set\", service_name, username],","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/network/auth.py#L136-L172","documentation":"Raised as a RuntimeError by KeyringCliProvider.get_auth_info when the external 'keyring' CLI subprocess exits with code 2 and its stderr contains both 'unrecognized arguments' and '--mode=creds'. pip invokes keyring with the '--mode=creds' flag, which only exists in keyring >= 25.2.1, so this signals an outdated keyring executable on PATH.","triggerScenarios":"pip is configured to fetch credentials via the keyring CLI (keyring_provider auto/subprocess/...) for an authenticated index, and the discovered 'keyring' executable is older than 25.2.1 and rejects the --mode=creds argument.","commonSituations":"System/virtualenv keyring package outdated relative to pip; multiple keyring installs and the wrong one is first on PATH; CI images shipping an old keyring; fresh containers that install keyring without pinning.","solutions":["Upgrade keyring: pip install --upgrade 'keyring>=25.2.1'.","Verify the version with 'keyring --version' and that the upgraded binary is the one pip discovers (check PATH / which keyring).","Pin 'keyring>=25.2.1' in your requirements/constraints so the floor is enforced.","If upgrade is impossible, disable the keyring CLI provider via --keyring-provider disabled or pip.conf."],"exampleFix":"# before\n$ keyring --version\nkeyring 20.x\n\n# after\n$ pip install -U 'keyring>=25.2.1'\n$ keyring --version\nkeyring 25.2.1","handlingStrategy":"validation","validationCode":"import shutil, subprocess\n\ndef keyring_version_ok(minimum=(25, 2, 1)) -> bool:\n    exe = shutil.which(\"keyring\")\n    if not exe:\n        return False\n    out = subprocess.run([exe, \"--version\"], capture_output=True, text=True)\n    nums = [int(x) for x in out.stdout.split() if x.split(\".\")[0].isdigit()][0]\n    return tuple(int(x) for x in out.stdout.strip().split()[-1].split(\".\")) >= minimum","typeGuard":null,"tryCatchPattern":"from pip._internal.exceptions import PipError\ntry:\n    pip_command.main([\"install\", \"pkg\"])\nexcept RuntimeError as e:\n    if \"Keyring util is outdated\" in str(e):\n        # upgrade keyring and retry\n        ...\n    raise","preventionTips":["Pin 'keyring>=25.2.1' in requirements/constraints.","Verify 'keyring --version' on CI and dev images.","Ensure the keyring on PATH is the upgraded one."],"tags":["authentication","keyring","version-mismatch","subprocess"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}