ansible/ansible · error · UnarchiveError

Unable to list files in the archive

Error message

Unable to list files in the archive

What it means

While computing CRCs, unarchive iterates zipfile.infolist(); any unexpected Exception during that listing is converted to UnarchiveError('Unable to list files in the archive'). Unlike the BadZipFile path, the archive opened but its central directory is inconsistent enough that listing raised.

Source

Thrown at lib/ansible/modules/unarchive.py:385

        if self._infodict:
            return self._infodict[path]

        try:
            archive = ZipFile(self.src)
        except BadZipFile as e:
            if e.args[0].lower().startswith('bad magic number'):
                # Python2.4 can't handle zipfiles with > 64K files.  Try using
                # /usr/bin/unzip instead
                self._legacy_file_list()
            else:
                raise
        else:
            try:
                for item in archive.infolist():
                    self._infodict[item.filename] = int(item.CRC)
            except Exception:
                archive.close()
                raise UnarchiveError('Unable to list files in the archive')

        return self._infodict[path]

    @property
    def files_in_archive(self):
        if self._files_in_archive:
            return self._files_in_archive

        self._files_in_archive = []
        try:
            archive = ZipFile(self.src)
        except BadZipFile as e:
            if e.args[0].lower().startswith('bad magic number'):
                # Python2.4 can't handle zipfiles with > 64K files.  Try using
                # /usr/bin/unzip instead
                self._legacy_file_list()
            else:
                raise

View on GitHub (pinned to 9cf16a4aca)

Solutions

  1. Test the archive independently: python3 -c "import zipfile; zipfile.ZipFile('x.zip').infolist()"
  2. Re-download or re-create the archive (checksum it)
  3. Regenerate the zip with a mainstream tool (standard zip) if the producer is exotic
  4. Ensure no concurrent writer touches src during the task

Example fix

# before
- ansible.builtin.unarchive:
    src: /tmp/app.zip
    dest: /opt/app
    remote_src: true

# after: pre-validate on target
- name: validate zip
  ansible.builtin.command: python3 -c "import zipfile; zipfile.ZipFile('/tmp/app.zip').infolist()"
  changed_when: false
- ansible.builtin.unarchive:
    src: /tmp/app.zip
    dest: /opt/app
    remote_src: true
Defensive patterns

Strategy: try-catch

Validate before calling

import zipfile

def zip_lists_cleanly(path):
    try:
        with zipfile.ZipFile(path) as z:
            z.infolist()
        return True
    except Exception:
        return False

Try / catch

try:
    crc = handler._crc32(path)
except UnarchiveError as e:
    module.fail_json(msg=str(e), hint='zip central directory unreadable; re-create archive')

Prevention

When it happens

Trigger: A zip whose central directory references corrupt/oversized entries; a file that changes concurrently while being listed; a crafted zip triggering a Python zipfile internal error.

Common situations: Damaged downloads; archives produced by tools with nonstandard zip dialects; reading an archive still being written by another process.

Related errors


AI-assisted analysis of ansible/ansible@9cf16a4aca (2026-08-15). Data as JSON: /api/errors/3fd08aa178b0705b. Report an issue: GitHub.