{"record":{"id":"b9d2124e73bd9dbe","repo":"ansible/ansible","slug":"unable-to-extract-s-from-collection","errorCode":null,"errorMessage":"Unable to extract '%s' from collection","messagePattern":"Unable to extract '(.+?)' from collection","errorType":"exception","errorClass":"AnsibleError","httpStatus":null,"severity":"error","filePath":"lib/ansible/galaxy/collection/__init__.py","lineNumber":1690,"sourceCode":"    collection_output_path = _build_collection_dir(\n        b_collection_path, b_collection_output_path,\n        collection_manifest, file_manifest,\n    )\n\n    display.display(\n        'Created collection for {coll!s} at {path!s}'.\n        format(coll=collection, path=collection_output_path)\n    )\n\n\ndef _extract_tar_dir(tar, dirname, b_dest):\n    \"\"\" Extracts a directory from a collection tar. \"\"\"\n    dirname = to_native(dirname, errors='surrogate_or_strict')\n\n    try:\n        tar_member = tar.getmember(dirname)\n    except KeyError:\n        raise AnsibleError(\"Unable to extract '%s' from collection\" % dirname)\n\n    b_dir_path = os.path.join(b_dest, to_bytes(dirname, errors='surrogate_or_strict'))\n\n    b_parent_path = os.path.dirname(b_dir_path)\n    os.makedirs(b_parent_path, mode=S_IRWXU_RXG_RXO, exist_ok=True)\n\n    if tar_member.type == tarfile.SYMTYPE:\n        b_link_path = to_bytes(tar_member.linkname, errors='surrogate_or_strict')\n        if not _is_child_path(b_link_path, b_dest, link_name=b_dir_path):\n            raise AnsibleError(\"Cannot extract symlink '%s' in collection: path points to location outside of \"\n                               \"collection '%s'\" % (to_native(dirname), b_link_path))\n\n        os.symlink(b_link_path, b_dir_path)\n\n    else:\n        if not os.path.isdir(b_dir_path):\n            os.mkdir(b_dir_path, S_IRWXU_RXG_RXO)\n","sourceCodeStart":1672,"sourceCodeEnd":1708,"githubUrl":"https://github.com/ansible/ansible/blob/9cf16a4aca7898481c257f1e17ad28d0b67b1f85/lib/ansible/galaxy/collection/__init__.py#L1672-L1708","documentation":"Raised in `_extract_tar_dir` when extracting a directory entry from a collection tarball and `tar.getmember(dirname)` raises KeyError, i.e. the tar archive has no member with that directory name. It means the collection tarball's manifest and its actual contents are out of sync.","triggerScenarios":"Installing a tarball whose MANIFEST.json/file_info lists a directory (e.g. `plugins/`) but the tar contains no such member; typically a hand-built or corrupted tarball rather than one produced by `ansible-galaxy collection build`.","commonSituations":"Manually repacked/crafted collection tarballs, truncated downloads, tools that strip directory entries from tars, collections built with mismatched metadata.","solutions":["Re-download the collection tarball (verify sha256 if available) and retry the install","Rebuild the tarball with `ansible-galaxy collection build` so directory entries and metadata agree","Inspect the archive (`tar -tzf collection.tar.gz`) to confirm the missing dir entry, then fix the packaging script that created it"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import tarfile\n\ndef tar_has_member(path, name):\n    with tarfile.open(path) as tf:\n        try:\n            tf.getmember(name)\n            return True\n        except KeyError:\n            return False\n\n# verify required entries before install\nassert tar_has_member('coll.tar.gz', 'MANIFEST.json')","typeGuard":null,"tryCatchPattern":"from ansible.errors import AnsibleError\ntry:\n    ansible.galaxy.collection install path\nexcept AnsibleError as e:\n    if \"Unable to extract\" in str(e):\n        # re-download or rebuild tarball; log tar -tzf listing","preventionTips":["Only consume tarballs produced by ansible-galaxy collection build or served by Galaxy","Verify artifact sha256 before installing","Automate installs from pinned requirements.yml, not ad-hoc files"],"tags":["ansible-galaxy","tarball","corruption","collection-install"],"backgroundTag":null,"analyzedSha":"9cf16a4aca7898481c257f1e17ad28d0b67b1f85","analyzedAt":"2026-08-15T00:15:47.100Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}