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
- 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.
- Strip/normalize any user-supplied path: reject leading backslash/drive letters and '..' segments before passing to pkg_resources.
- 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
- Build resource names with forward slashes as relative paths, never os.path.join.
- Reject '..' and absolute/backslash paths from user input before the resource API.
- Use posixpath.join (not os.path.join) when assembling resource names.
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
- Invalid script entry point name {entry.name!r}: the script w
- The wheel {wheel_path!r} has a file {target_path!r} trying t
- Path {path!r} in pylock file obtained from a URL resolves ou
- The zip file ({}) has a file ({}) trying to install outside
- Invalid member in the tar file {}: {}
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/d55801d64dd7969f.json.
Report an issue: GitHub.