{"id":"c88a90cf687c5ada","repo":"python-poetry/poetry","slug":"no-usable-hash-type-s-for-package-from-archive","errorCode":null,"errorMessage":"No usable hash type(s) for {package} from archive {archive.name} found (known hashes: {known_hashes!s})","messagePattern":"No usable hash type\\(s\\) for (.+?) from archive (.+?) found \\(known hashes: (.+?)\\)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/poetry/installation/executor.py","lineNumber":801,"sourceCode":"\n        # Use the original archive to provide the correct hash.\n        self._populate_hashes_dict(original_archive, package)\n\n        return archive\n\n    def _populate_hashes_dict(self, archive: Path, package: Package) -> None:\n        if package.files and archive.name in {f[\"file\"] for f in package.files}:\n            archive_hash = self._validate_archive_hash(archive, package)\n            self._hashes[package.name] = archive_hash\n\n    @staticmethod\n    def _validate_archive_hash(archive: Path, package: Package) -> str:\n        known_hashes = {f[\"hash\"] for f in package.files if f[\"file\"] == archive.name}\n        hash_types = {t.split(\":\")[0] for t in known_hashes}\n        hash_type = get_highest_priority_hash_type(hash_types, archive.name)\n\n        if hash_type is None:\n            raise RuntimeError(\n                f\"No usable hash type(s) for {package} from archive\"\n                f\" {archive.name} found (known hashes: {known_hashes!s})\"\n            )\n\n        archive_hash = f\"{hash_type}:{get_file_hash(archive, hash_type)}\"\n\n        if archive_hash not in known_hashes:\n            raise RuntimeError(\n                f\"Hash for {package} from archive {archive.name} not found in\"\n                f\" known hashes (was: {archive_hash})\"\n            )\n\n        return archive_hash\n\n    def _download_archive(\n        self,\n        operation: Install | Update,\n        url: str,","sourceCodeStart":783,"sourceCodeEnd":819,"githubUrl":"https://github.com/python-poetry/poetry/blob/92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54/src/poetry/installation/executor.py#L783-L819","documentation":"Raised by Executor._validate_archive_hash at src/poetry/installation/executor.py:794-804 when the set of hash types recorded for the archive in package.files, passed through get_highest_priority_hash_type, yields no usable type. The archive has a record entry but none of its hash types are in the priority list. RuntimeError.","triggerScenarios":"package.files contains entries for archive.name whose 'hash' fields use hash algorithms Poetry does not consider usable (e.g. only 'md5' or an unknown scheme). Encountered during _populate_hashes_dict → _validate_archive_hash at install time.","commonSituations":"A lock file generated by an old/modified Poetry that recorded only weak hash types; a manually edited lock file; a package source that publishes only md5 hashes; lock file corruption.","solutions":["Regenerate the lock so it records sha256: `poetry lock --no-cache --regenerate`.","Inspect poetry.lock for the package's files block and confirm hash values start with a supported algorithm (sha256 preferred).","If the upstream index only publishes weak hashes, switch to an index that publishes sha256 or accept the limitation by removing the package's files entry (not recommended)."],"exampleFix":"# before (poetry.lock)\n[[package.files]]\nfile = \"pkg-1.0-py3-none-any.whl\"\nhash = \"md5:abc123...\"\n\n# after\n$ poetry lock --no-cache --regenerate\n# (lock now records sha256:...)","handlingStrategy":"validation","validationCode":"from poetry.utils.hashes import get_highest_priority_hash_type\n\nfor f in package.files:\n    types = {h.split(':')[0] for h in [f['hash']]}\n    if get_highest_priority_hash_type(types, f['file']) is None:\n        raise ValueError(f\"No usable hash type for {f['file']}; regenerate lock with sha256.\")","typeGuard":null,"tryCatchPattern":"try:\n    executor.run(operations)\nexcept RuntimeError as e:\n    if 'No usable hash type' in str(e):\n        run('poetry', 'lock', '--no-cache', '--regenerate', check=True)\n        executor.run(operations)\n    raise","preventionTips":["Generate locks with current Poetry so sha256 is recorded.","Do not hand-edit hash fields in poetry.lock."],"tags":["checksum","integrity","hash","lock-file","installation"],"analyzedSha":"92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54","analyzedAt":"2026-08-04T20:33:34.072Z","schemaVersion":2}