pypa/pip · error · ValueError

Use of .. or absolute path in a resource path is not allowed

Error message

Use of .. or absolute path in a resource path is not allowed.

What it means

Raised as ValueError by NullProvider._validate_resource_path when a resource name is a Windows-style absolute path — specifically when it starts with a backslash or is absolute under ntpath semantics while not being a posix-absolute path. For posix-absolute paths and '..' traversal segments the method currently only emits a DeprecationWarning (and states it will raise in a future release), but Windows absolute paths are hard-rejected now. This enforces that resource names use forward-slash relative paths, never os.path-joined absolute or parent-traversal paths.

Source

Thrown at src/pip/_vendor/pkg_resources/__init__.py:1818

        >>> vrp(None)
        Traceback (most recent call last):
        ...
        AttributeError: ...
        """
        invalid = (
            os.path.pardir in path.split(posixpath.sep)
            or posixpath.isabs(path)
            or ntpath.isabs(path)
            or path.startswith("\\")
        )
        if not invalid:
            return

        msg = "Use of .. or absolute path in a resource path is not allowed."

        # Aggressively disallow Windows absolute paths
        if (path.startswith("\\") or ntpath.isabs(path)) and not posixpath.isabs(path):
            raise ValueError(msg)

        # for compatibility, warn; in future
        # raise ValueError(msg)
        issue_warning(
            msg[:-1] + " and will raise exceptions in a future release.",
            DeprecationWarning,
        )

    def _get(self, path) -> bytes:
        if hasattr(self.loader, 'get_data') and self.loader:
            # Already checked get_data exists
            return self.loader.get_data(path)  # type: ignore[attr-defined]
        raise NotImplementedError(
            "Can't perform this operation for loaders without 'get_data()'"
        )


register_loader_type(object, NullProvider)

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Always build resource names with forward slashes as relative paths: use posixpath.join or literal 'pkg/data.txt' strings, never os.path.join with OS separators.
  2. Strip/normalize any user-supplied path: reject leading backslash/drive letters and '..' segments before passing to pkg_resources.
  3. For absolute or traversal-prone inputs, resolve them outside pkg_resources (e.g. via pathlib) rather than passing through the resource API.

Example fix

// before
import os
path = pkg_resources.resource_filename('pkg', os.path.join('data', 'f.txt'))  # ValueError on Windows

// after
path = pkg_resources.resource_filename('pkg', 'data/f.txt')  # forward-slash relative
Defensive patterns

Strategy: validation

Validate before calling

import posixpath, ntpath, os

def valid_resource_path(name):
    if not isinstance(name, str):
        return False
    invalid = (
        os.path.pardir in name.split(posixpath.sep)
        or posixpath.isabs(name)
        or ntpath.isabs(name)
        or name.startswith('\\')
    )
    return not invalid

Type guard

import posixpath, ntpath, os

def is_safe_resource_path(name: str) -> bool:
    return isinstance(name, str) and not (
        os.path.pardir in name.split(posixpath.sep)
        or posixpath.isabs(name)
        or ntpath.isabs(name)
        or name.startswith('\\')
    )

Try / catch

try:
    path = pkg_resources.resource_filename(pkg, name)
except ValueError as e:
    if 'resource path' in str(e):
        raise ValueError(f'unsafe resource name {name!r}') from e
    raise

Prevention

When it happens

Trigger: Passing a resource_name like '\\share\file', 'C:\data\file.txt', or any backslash-leading/drive-prefixed string to resource access APIs (resource_filename, resource_string, has_resource, etc.). _validate_resource_path is called by _fn on every resource path.

Common situations: Accidentally using os.path.join or a Windows path variable as a resource name instead of a forward-slash relative name; security-sensitive code rejecting path traversal; code that worked on POSIX but hard-fails on Windows due to backslash handling.

Related errors


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