pypa/pip · error · InstallationError
Index {link.comes_from} does not provide upload-time metadat
Error message
Index {link.comes_from} does not provide upload-time metadata. What it means
Raised by get_install_candidate when a LinkEvaluator returns LinkType.upload_time_missing. This happens when the --uploaded-prior-to option is set but the package index page (or find-links source) for the link does not include upload-time metadata for that file. Because pip cannot honor a date filter without a timestamp, it aborts immediately rather than silently skipping the constraint.
Source
Thrown at src/pip/_internal/index/package_finder.py:828
def _log_skipped_link(self, link: Link, result: LinkType, detail: str) -> None:
# Put the link at the end so the reason is more visible and because
# the link string is usually very long.
logger.debug("Skipping link: %s: %s", detail, link)
if result == LinkType.requires_python_mismatch:
self._requires_python_skipped.add(detail)
def get_install_candidate(
self, link_evaluator: LinkEvaluator, link: Link
) -> InstallationCandidate | None:
"""
If the link is a candidate for install, convert it to an
InstallationCandidate and return it. Otherwise, return None.
"""
result, detail = link_evaluator.evaluate_link(link)
if result == LinkType.upload_time_missing:
# Fail immediately if the index doesn't provide upload-time
# when --uploaded-prior-to is specified
raise InstallationError(detail)
if result != LinkType.candidate:
self._log_skipped_link(link, result, detail)
return None
try:
return InstallationCandidate(
name=link_evaluator.project_name,
link=link,
version=detail,
)
except InvalidVersion:
return None
def evaluate_links(
self, link_evaluator: LinkEvaluator, links: Iterable[Link]
) -> list[InstallationCandidate]:
"""
Convert links that are candidates to InstallationCandidate objects.View on GitHub (pinned to f399c37189)
Solutions
- Drop the --uploaded-prior-to flag if date-based filtering is not strictly required.
- Point --index-url at a source that provides upload-time metadata (PyPI, or configure your mirror to include the upload-time attribute on simple-index links).
- If using a local --find-links directory, regenerate the index HTML with a tool that records file mtime as upload time.
Example fix
// before pip install --uploaded-prior-to 2024-01-01 mypkg -i https://internal-simple/ // after (flag removed) pip install mypkg -i https://internal-simple/
Defensive patterns
Strategy: validation
Validate before calling
// Before using --uploaded-prior-to, confirm the index emits upload-time metadata
// by fetching a simple-index page and checking for the upload-time attribute:
import urllib.request, html.parser
class T(html.parser.HTMLParser):
has_upload = False
def handle_starttag(self, tag, attrs):
if dict(attrs).get('data-upload-time'):
self.has_upload = True
p = T(); p.feed(urllib.request.urlopen(index_url + project + '/').read().decode())
if not p.has_upload:
raise SystemExit('index lacks upload-time metadata; drop --uploaded-prior-to') Try / catch
from pip._internal.exceptions import InstallationError
try:
finder.get_install_candidate(evaluator, link)
except InstallationError as e:
if 'upload-time' in str(e):
# retry without --uploaded-prior-to or switch index
... Prevention
- Verify your index/mirror supports upload-time metadata before adopting --uploaded-prior-to.
- Avoid --uploaded-prior-to against plain find-links directories.
- In automation, catch InstallationError and degrade gracefully (drop the flag) if the index is unsupported.
When it happens
Trigger: Running `pip install --uploaded-prior-to <DATE> <pkg>` against a simple-index URL or --find-links directory whose PEP 503 page lacks the upload-time attribute on the link. The get_install_candidate method at package_finder.py:824 evaluates the link and, on result == LinkType.upload_time_missing, raises InstallationError(detail) where detail is the message.
Common situations: Private mirrors / internal indexes (devpi, Artifactory, Nexus simple repos) that strip or never emit upload timestamps; legacy flat find-links directories with no HTML wrapper; a mirror that only provides the file URL without HTTP Last-Modified-style metadata pip can map to upload time.
Related errors
- No matching distribution found for {req}
- Requested {ireq} has inconsistent Name between its PEP 658 .
- Requested {ireq} has inconsistent Version between its PEP 65
- Requested {ireq} has inconsistent Requires-Dist between its
- Requested {ireq} has inconsistent Requires-Python between it
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/8aced6d6d8c5c1f5.
Report an issue: GitHub.