Skip to content

[bug] PermissionError during conan cache restore when extracting read-only files on Windows #20241

Description

@danimtb

Describe the bug

Conan Version: 2.31.1
Operating System: Windows 11
Python Version: Python 3.12.0


Description

When running conan cache restore on Windows, the extraction fails with PermissionError: [Errno 13] Permission denied.

This occurs when an archive contains read-only files—such as MSYS2 system files (etc/pki/ca-trust/...), Git pack files (.git/objects/pack/*.idx), or pre-existing cache files marked as read-only. Python’s tarfile.extractall() is unable to open these existing files in write mode (wb) on Windows, causing the restore process to crash.


Logs / Traceback

λ conan cache restore ros-cache.tgz
ERROR: Traceback (most recent call last):
  File "C:\python\Lib\site-packages\conan\cli\cli.py", line 297, in main
    cli.run(args)
  File "C:\python\Lib\site-packages\conan\cli\cli.py", line 194, in run
    command.run(self._conan_api, args[0][1:])
  File "C:\python\Lib\site-packages\conan\cli\command.py", line 213, in run
    sub.run(conan_api, parser, *args)
  File "C:\python\Lib\site-packages\conan\cli\command.py", line 231, in run
    info = self._method(conan_api, parent_parser, self._parser, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\python\Lib\site-packages\conan\cli\commands\cache.py", line 335, in cache_restore
    package_list = conan_api.cache.restore(path)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\python\Lib\site-packages\conan\api\subapi\cache.py", line 399, in restore
    the_tar.extractall(path=cache_folder)
  File "C:\python\Lib\tarfile.py", line 2268, in extractall
    self._extract_one(tarinfo, path, set_attrs=not tarinfo.isdir(),
  File "C:\python\Lib\tarfile.py", line 2335, in _extract_one
    self._handle_fatal_error(e)
  File "C:\python\Lib\tarfile.py", line 2331, in _extract_one
    self._extract_member(tarinfo, os.path.join(path, tarinfo.name),
  File "C:\python\Lib\tarfile.py", line 2414, in _extract_member
    self.makefile(tarinfo, targetpath)
  File "C:\python\Lib\tarfile.py", line 2459, in makefile
    with bltn_open(targetpath, "wb") as target:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied: 'C:\\.c2-reloc\\p\\msys2f91ae1bf3386a\\p\\bin\\msys64\\etc\\pki\\ca-trust\\extracted\\java\\cacerts'

ERROR: [Errno 13] Permission denied: 'C:\\.c2-reloc\\p\\msys2f91ae1bf3386a\\p\\bin\\msys64\\etc\\pki\\ca-trust\\extracted\\java\\cacerts'


Expected Behavior

conan cache restore should handle pre-existing read-only attributes on Windows and extract files successfully without raising a PermissionError.


Possible Fix

In conan/api/subapi/cache.py, adjust destination file permissions before extraction to ensure they are writable:

import os
import stat

# ... inside cache restore logic ...
for member in the_tar.getmembers():
    target_path = os.path.join(cache_folder, member.name)
    if os.path.exists(target_path):
        os.chmod(target_path, stat.S_IWRITE | stat.S_IREAD)

the_tar.extractall(path=cache_folder)

How to reproduce it

  1. Create a Conan package that includes read-only files (e.g., an MSYS2 environment or a Git repository source directory).
  2. Save the cache using conan cache save ... -f ros-cache.tgz.
  3. Restore the archive on a Windows system using conan cache restore ros-cache.tgz.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions