pypa/pip · critical · InstallationError

Invalid member in the tar file {}: {}

Error message

Invalid member in the tar file {}: {}

What it means

InstallationError raised when extracting a tar archive and the underlying Python tarfile filter raises a TarError (e.g. a member that the data_filter rejects for safety). pip's pip_filter wraps the member extraction; any tarfile.TarError propagates as this user-facing message identifying the archive and the offending member. It is the tar equivalent of the zip path-traversal guard but covers all data_filter violations.

Source

Thrown at src/pip/_internal/utils/unpacking.py:238

                    except tarfile.LinkOutsideDestinationError:
                        if sys.version_info[:3] in {
                            (3, 9, 17),
                            (3, 10, 12),
                            (3, 11, 4),
                        }:
                            # The tarfile filter in specific Python versions
                            # raises LinkOutsideDestinationError on valid input
                            # (https://github.com/python/cpython/issues/107845)
                            # Ignore the error there, but do use the
                            # more lax `tar_filter`
                            member = tarfile.tar_filter(member, location)
                        else:
                            raise
                except tarfile.TarError as exc:
                    message = "Invalid member in the tar file {}: {}"
                    # Filter error messages mention the member name.
                    # No need to add it here.
                    raise InstallationError(
                        message.format(
                            filename,
                            exc,
                        )
                    )
                if member.isfile() and orig_mode & 0o111:
                    member.mode = default_mode_plus_executable
                else:
                    # See PEP 706 note above.
                    # The PEP changed this from `int` to `Optional[int]`,
                    # where None means "use the default". Mypy doesn't
                    # know this yet.
                    member.mode = None  # type: ignore [assignment]
                return member

            tar.extractall(location, filter=pip_filter)

    finally:

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Inspect the tar with `tar -tvf file.tar.gz` and locate the offending member named in the error.
  2. Reject and re-download from a trusted source; verify the hash.
  3. If legitimately benign, rebuild the archive without the offending member.
  4. Keep pip current so its data_filter rules match upstream CPython.

Example fix

// before
untar_file('pkg.tar.gz', '/target')  # contains a device node / absolute path

// after
# rebuild the archive with safe members:
tar --sort=name --mtime='UTC 1970-01-01' -czf pkg.tar.gz -C src .
Defensive patterns

Strategy: validation

Validate before calling

import tarfile
def tar_is_safe(path: str) -> bool:
    try:
        with tarfile.open(path) as t:
            for m in t.getmembers():
                if m.name.startswith('/') or '..' in m.name.split('/'):
                    return False
                if m.issym() or m.islnk():
                    if m.linkname.startswith('/') or '..' in m.linkname.split('/'):
                        return False
        return True
    except tarfile.TarError:
        return False

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Unpacking a .tar.gz/.tar.bz2/.tar.xz source distribution where a member triggers tarfile's data_filter rejection (link/absolute path traversal, device files, etc.). Triggered from untar_file's pip_filter on Python 3.12+ (or backported filter).

Common situations: Malicious sdist; legacy tar with absolute paths; tar containing device nodes; older archive created before PEP 706 filtering conventions.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/40a0972a1163f806.json. Report an issue: GitHub.