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

  1. Drop the --uploaded-prior-to flag if date-based filtering is not strictly required.
  2. 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).
  3. 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

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


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/8aced6d6d8c5c1f5. Report an issue: GitHub.