{"record":{"id":"7f37f36845a64453","repo":"pypa/pip","slug":"unknown-hash-name-hash-name","errorCode":null,"errorMessage":"Unknown hash name: {hash_name}","messagePattern":"Unknown hash name: (.+?)","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/utils/hashes.py","lineNumber":81,"sourceCode":"        return sum(len(digests) for digests in self._allowed.values())\n\n    def is_hash_allowed(self, hash_name: str, hex_digest: str) -> bool:\n        \"\"\"Return whether the given hex digest is allowed.\"\"\"\n        return hex_digest in self._allowed.get(hash_name, [])\n\n    def check_against_chunks(self, chunks: Iterable[bytes]) -> None:\n        \"\"\"Check good hashes against ones built from iterable of chunks of\n        data.\n\n        Raise HashMismatch if none match.\n\n        \"\"\"\n        gots = {}\n        for hash_name in self._allowed.keys():\n            try:\n                gots[hash_name] = hashlib.new(hash_name)\n            except (ValueError, TypeError):\n                raise InstallationError(f\"Unknown hash name: {hash_name}\")\n\n        for chunk in chunks:\n            for hash in gots.values():\n                hash.update(chunk)\n\n        for hash_name, got in gots.items():\n            if got.hexdigest() in self._allowed[hash_name]:\n                return\n        self._raise(gots)\n\n    def _raise(self, gots: dict[str, _Hash]) -> NoReturn:\n        raise HashMismatch(self._allowed, gots)\n\n    def check_against_file(self, file: BinaryIO) -> None:\n        \"\"\"Check good hashes against a file-like object\n\n        Raise HashMismatch if none match.\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/utils/hashes.py#L63-L99","documentation":"Raised as InstallationError by Hashes.check_against_chunks when hashlib.new(hash_name) throws ValueError or TypeError, meaning the hash algorithm name specified in a requirement's --hash is not recognised by the system's hashlib. pip only allows algorithms listed in STRONG_HASHES (sha256, sha384, sha512) at the requirements-parsing layer, but this guard catches any that slip through or are computed at runtime. The error names the offending algorithm so the user can correct it.","triggerScenarios":"A requirements file or pylock file containing a --hash line with a misspelled or unsupported algorithm name (e.g. `--hash=sha235:...`, `--hash=md5:...`). The loop at hashes.py:77-81 calls hashlib.new for each key in self._allowed and raises on failure.","commonSituations":"Typos in hash algorithm names in requirements files. Copying hashes generated by a tool that outputs non-strong algorithm names (md5, sha1). Manually editing requirements files and introducing a syntax error in the hash spec. Using a hash name valid on one platform but not another (e.g. OpenSSL-linked algorithms).","solutions":["Correct the algorithm name in the requirements file to one of sha256, sha384, or sha512.","Regenerate the hash with `pip hash <file>` which always uses sha256.","Remove the malformed --hash line entirely if you are not in --require-hashes mode.","If a legitimate algorithm is rejected, verify your Python/OpenSSL build supports it with `python -c \"import hashlib; hashlib.new('sha256')\"`."],"exampleFix":"// before\npkg==1.0 --hash=sha235:abc123...\n\n// after\npkg==1.0 --hash=sha256:abc123...","handlingStrategy":"validation","validationCode":"import hashlib\n\nVALID_HASH_NAMES = {'sha256', 'sha384', 'sha512'}\n\ndef validate_hash_lines(requirements_path: str) -> list[str]:\n    \"\"\"Return list of invalid --hash lines in a requirements file.\"\"\"\n    import re\n    errors = []\n    pattern = re.compile(r'--hash=([a-zA-Z0-9]+):')\n    with open(requirements_path) as f:\n        for i, line in enumerate(f, 1):\n            for m in pattern.finditer(line):\n                algo = m.group(1).lower()\n                if algo not in VALID_HASH_NAMES:\n                    errors.append(f'Line {i}: unknown hash algo {algo!r}')\n    return errors","typeGuard":"def is_valid_hash_name(name: str) -> bool:\n    \"\"\"True if the hash algorithm is supported by pip's --hash.\"\"\"\n    return name.lower() in {'sha256', 'sha384', 'sha512'}","tryCatchPattern":null,"preventionTips":["Always generate hashes with `pip hash <file>` which uses sha256.","Lint requirements files for --hash algorithm names before installing.","Avoid md5/sha1 hashes — pip only accepts strong hash algorithms."],"tags":["hashes","validation","requirements-file","hashlib"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}