pypa/pip · error · CommandError

XMLRPC request failed [code: {fault.faultCode}] {fault.fault

Error message

XMLRPC request failed [code: {fault.faultCode}]
{fault.faultString}

What it means

Raised as CommandError in SearchCommand.search() at search.py:79-83 when the PyPI XMLRPC search call returns an xmlrpc.client.Fault. The fault code and fault string from the server are formatted into the message. Historically this is most common because PyPI deprecated and then disabled its XMLRPC search endpoint.

Source

Thrown at src/pip/_internal/commands/search.py:83

        print_results(hits, terminal_width=terminal_width)
        if pypi_hits:
            return SUCCESS
        return NO_MATCHES_FOUND

    def search(self, query: list[str], options: Values) -> list[dict[str, str]]:
        index_url = options.index

        session = self.get_default_session(options)

        transport = PipXmlrpcTransport(index_url, session)
        pypi = xmlrpc.client.ServerProxy(index_url, transport)
        try:
            hits = pypi.search({"name": query, "summary": query}, "or")
        except xmlrpc.client.Fault as fault:
            message = (
                f"XMLRPC request failed [code: {fault.faultCode}]\n{fault.faultString}"
            )
            raise CommandError(message)
        assert isinstance(hits, list)
        return hits


def transform_hits(hits: list[dict[str, str]]) -> list[TransformedHit]:
    """
    The list from pypi is really a list of versions. We want a list of
    packages with the list of versions stored inline. This converts the
    list from pypi into one we can use.
    """
    packages: dict[str, TransformedHit] = OrderedDict()
    for hit in hits:
        name = hit["name"]
        summary = hit["summary"]
        version = hit["version"]

        if name not in packages.keys():
            packages[name] = {

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Stop using 'pip search' — PyPI removed the XMLRPC search endpoint; use the PyPI website or a third-party tool instead.
  2. Point --index at a mirror that still supports XMLRPC search, if you have one.
  3. Upgrade pip; modern versions warn that 'pip search' is deprecated/unavailable.
  4. For programmatic queries, use the PyPI JSON API (https://pypi.org/pypi/<project>/json) directly.

Example fix

# before
pip search requests  # XMLRPC disabled on PyPI
# after — query the JSON API
curl -s https://pypi.org/pypi/requests/json | jq '.info.summary'
Defensive patterns

Strategy: fallback

Validate before calling

# PyPI XMLRPC search is disabled; detect availability before relying on it
import urllib.request
try:
    urllib.request.urlopen('https://pypi.org/search/?q=requests', timeout=5)
    search_available = False  # HTML search exists but XMLRPC does not
except Exception:
    search_available = False
print('pip search via XMLRPC is unavailable; use the web/JSON API')

Try / catch

import subprocess, xmlrpc.client
try:
    subprocess.run(['pip','search','requests'], check=True)
except subprocess.CalledProcessError:
    # fallback to the PyPI JSON API
    import json, urllib.request
    data = json.load(urllib.request.urlopen('https://pypi.org/pypi/requests/json'))
    print(data['info']['summary'])

Prevention

When it happens

Trigger: Running 'pip search <query>' against an index URL (default PyPI) whose XMLRPC search endpoint returns a Fault. The try/except at search.py:77-83 catches xmlrpc.client.Fault raised by pypi.search().

Common situations: PyPI permanently disabled the legacy XMLRPC search (HTTP 410 / fault); corporate mirror that does not implement search; network appliance returning an XMLRPC fault; very old pip against a changed server contract.

Related errors


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