{"record":{"id":"85e58399db08522a","repo":"ansible/ansible","slug":"zip-info-perm-format-incorrect-s","errorCode":null,"errorMessage":"ZIP info perm format incorrect, %s","messagePattern":"ZIP info perm format incorrect, (.+?)","errorType":"exception","errorClass":"UnarchiveError","httpStatus":null,"severity":"error","filePath":"lib/ansible/modules/unarchive.py","lineNumber":605,"sourceCode":"                elif permstr == 'rwx---':\n                    permstr = 'rwxrwxrwx'\n                else:\n                    permstr = 'rw-rw-rw-'\n                file_umask = umask\n            elif len(permstr) == 7:\n                if permstr == 'rwxa---':\n                    permstr = 'rwxrwxrwx'\n                else:\n                    permstr = 'rw-rw-rw-'\n                file_umask = umask\n            elif 'bsd' in systemtype.lower():\n                file_umask = umask\n            else:\n                file_umask = 0\n\n            # Test string conformity\n            if len(permstr) != 9 or not ZIP_FILE_MODE_RE.match(permstr):\n                raise UnarchiveError('ZIP info perm format incorrect, %s' % permstr)\n\n            # DEBUG\n#            err += \"%s%s %10d %s\\n\" % (ztype, permstr, size, path)\n\n            b_dest = os.path.join(self.b_dest, to_bytes(path, errors='surrogate_or_strict'))\n            try:\n                st = os.lstat(b_dest)\n            except Exception:\n                change = True\n                self.includes.append(path)\n                err += 'Path %s is missing\\n' % path\n                diff += '>%s++++++.?? %s\\n' % (ftype, path)\n                continue\n\n            # Compare file types\n            if ftype == 'd' and not stat.S_ISDIR(st.st_mode):\n                change = True\n                self.includes.append(path)","sourceCodeStart":587,"sourceCodeEnd":623,"githubUrl":"https://github.com/ansible/ansible/blob/9cf16a4aca7898481c257f1e17ad28d0b67b1f85/lib/ansible/modules/unarchive.py#L587-L623","documentation":"When unarchive must shell out to 'unzip -Z (zipinfo)' to inspect permissions, it validates each entry's permission string against a 9-char rwx regex (ZIP_FILE_MODE_RE). If the listing line yields a perm field that is not 9 rwx-style characters, it raises this UnarchiveError naming the offending permstr.","triggerScenarios":"unzip -Z output on a non-GNU/BSD system whose locale or unzip build formats the permissions field differently; exotic zip entries with unusual attribute encodings; parsing drift after an unzip version change.","commonSituations":"BusyBox unzip variants; unzip 6.3+ with different column output; archives with entries created by Info-ZIP flags the parser does not expect.","solutions":["Run unzip -Z /path/archive.zip on the host and compare the permissions column to standard rwxrwxrwx format","Upgrade/downgrade unzip to the standard Info-ZIP release the parser expects","Set explicit permissions in the task (mode:) or use the Python zipfile path (keep unzip out) by ensuring python3-zipfile is usable","Recreate the zip with standard permissions (e.g. zip -X) to normalize the fields"],"exampleFix":"# before\n- ansible.builtin.unarchive:\n    src: /tmp/app.zip\n    dest: /opt/app\n    remote_src: true\n# UnarchiveError: ZIP info perm format incorrect, rwxa---\n\n# after: normalize archive on the build side\n# zip -X -r app.zip app/   (drops extra attribute fields)\n- ansible.builtin.unarchive:\n    src: /tmp/app.zip\n    dest: /opt/app\n    remote_src: true\n    mode: '0755'","handlingStrategy":"validation","validationCode":"import re\nZIP_FILE_MODE_RE = re.compile(r'^[rwxstT-]{9}$')\n\ndef permstr_ok(permstr):\n    return len(permstr) == 9 and bool(ZIP_FILE_MODE_RE.match(permstr))","typeGuard":null,"tryCatchPattern":"try:\n    handler.canonicalize_permissions(permstr)\nexcept UnarchiveError as e:\n    module.fail_json(msg=str(e), hint='unzip -Z output unexpected; standardize unzip version or rebuild zip')","preventionTips":["Pin a standard Info-ZIP unzip in target images","Create zips with zip -X to normalize attributes","Set explicit mode: in unarchive tasks to bypass zipinfo parsing"],"tags":["unarchive","zip","unzip","permissions","ansible-module"],"backgroundTag":null,"analyzedSha":"9cf16a4aca7898481c257f1e17ad28d0b67b1f85","analyzedAt":"2026-08-15T00:15:47.100Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}