Skip to content

Python3.9+ throws KeyError when extracting folder with trailing slash #127636

Closed

Description

@ovianao

Bug report

Bug description:

Calling extract() on a member of a tar file that is a directory and contains a trailing forward slash in its name in Python3.9+ causes a KeyError, since the member cannot be found due to what appears to be the trimmed slash here:

tarinfo = self._getmember(name.rstrip('/'))

import tarfile

def create_tar(archive_path):
    tar = tarfile.open(archive_path, 'w')
    t = tarfile.TarInfo('./mydir/')
    tar.addfile(t)
    tar.close()

def extract_tar(archive_path, dest):
    tar = None
    try:
        tar = tarfile.open(archive_path)
        for item in tar.getnames():
            tar.extract(item, dest)
    finally:
        if tar is not None:
            tar.close()

archive = '.\\test.tar'
dest = '.'
create_tar(archive)
extract_tar(archive, dest)

Results in:


Traceback (most recent call last):
  File "C:\temp\tar_test\test.py", line 23, in <module>
    extract_tar(archive, dest)
  File "C:\temp\tar_test\test.py", line 15, in extract_tar
    tar.extract(item, dest)
  File "c:\python39\lib\tarfile.py", line 2077, in extract
    tarinfo = self.getmember(member)
  File "c:\python39\lib\tarfile.py", line 1799, in getmember
    raise KeyError("filename %r not found" % name)
KeyError: "filename './mydir/' not found"

CPython versions tested on:

3.9 EDIT also 3.12.8 and 3.13.1.

Operating systems tested on:

Windows

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Dec 5, 2024
  2. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Dec 5, 2024
  3. ericvsmith commented on Dec 5, 2024

    @ericvsmith
    Member

    Have you verified this happens on bugfix supported versions of Python (3.12, 3.13)?

  4. ovianao commented on Dec 6, 2024

    @ovianao
    Author

    I've just verified that this indeed happens in both Python 3.12.8 as well as in 3.13.1.

    I must admit, that in my sample code above, I am not setting the TarInfo member type to tarfile.DIRTYPE. When I do set it, the trailing / is omitted from the name in the member when the sample Python code (above) adds it to the tar file.

    However, in my production code, I do end up having to work with a tar file which has a TarInfo member with the type tarfile.DIRTYPE and it does have a trailing / in its name. That tar file is not created by Python's tarfile module; my understanding is that it's being created by the tar cli itself. Still trying to figure out how that is happening, but the error presented by my sample code above is the same, caused by the same line of code that I pointed to. Indeed, if I make a modification to remove the rstrip on that line of code, my folder is extracted properly without error since the name is found.

    Also, if instead of passing in the member's name to the tar.extract() function, I instead pass the TarInfo object itself, that folder with the trailing / is extracted properly, so I can work around it that way.

    Unfortunately, I can't supply my "production" archive, since it contains product code names that can't be made public.

  5. yuanx749 commented on Aug 12, 2026

    @yuanx749
    Contributor

    Friendly ping for review when someone has time. Thanks!

  6. added a commit that references this issue on Sep 8, 2026
  7. self-assigned this
    on Sep 8, 2026
  8. gpshead commented on Sep 8, 2026

    @gpshead
    Member

    thanks for the fix, reviewed and set to automerge and backport.

  9. added a commit that references this issue on Sep 8, 2026
  10. added a commit that references this issue on Sep 12, 2026
  11. added a commit that references this issue on Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions