{"record":{"id":"43a5a3ae6af2c66f","repo":"pypa/pip","slug":"xmlrpc-request-failed-code-fault-faultcode-n","errorCode":null,"errorMessage":"XMLRPC request failed [code: {fault.faultCode}]\\n{fault.faultString}","messagePattern":"XMLRPC request failed \\[code: (.+?)\\]\\\\n(.+?)","errorType":"exception","errorClass":"CommandError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/commands/search.py","lineNumber":83,"sourceCode":"        print_results(hits, terminal_width=terminal_width)\n        if pypi_hits:\n            return SUCCESS\n        return NO_MATCHES_FOUND\n\n    def search(self, query: list[str], options: Values) -> list[dict[str, str]]:\n        index_url = options.index\n\n        session = self.get_default_session(options)\n\n        transport = PipXmlrpcTransport(index_url, session)\n        pypi = xmlrpc.client.ServerProxy(index_url, transport)\n        try:\n            hits = pypi.search({\"name\": query, \"summary\": query}, \"or\")\n        except xmlrpc.client.Fault as fault:\n            message = (\n                f\"XMLRPC request failed [code: {fault.faultCode}]\\n{fault.faultString}\"\n            )\n            raise CommandError(message)\n        assert isinstance(hits, list)\n        return hits\n\n\ndef transform_hits(hits: list[dict[str, str]]) -> list[TransformedHit]:\n    \"\"\"\n    The list from pypi is really a list of versions. We want a list of\n    packages with the list of versions stored inline. This converts the\n    list from pypi into one we can use.\n    \"\"\"\n    packages: dict[str, TransformedHit] = OrderedDict()\n    for hit in hits:\n        name = hit[\"name\"]\n        summary = hit[\"summary\"]\n        version = hit[\"version\"]\n\n        if name not in packages.keys():\n            packages[name] = {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/commands/search.py#L65-L101","documentation":"Raised by SearchCommand.search() when the XML-RPC call to the package index returns an xmlrpc.client.Fault. The fault code and fault string from the remote server are embedded in the message. Most commonly this occurs because PyPI permanently deprecated and disabled its XML-RPC search endpoint, causing every search request to fault server-side.","triggerScenarios":"Calling `pip search <query>` against pypi.org (default), or against a custom --index that does not implement the XML-RPC search method, or when a proxy/firewall returns a fault-formatted response.","commonSituations":"Any modern invocation of `pip search` against PyPI, since PyPI removed XML-RPC search support; using a private index that lacks the search method; intermittent network/proxy issues that corrupt the XML-RPC payload.","solutions":["Stop using `pip search`; PyPI no longer supports it. Search via the PyPI website (pypi.org/search) or the JSON API instead.","If using a private/custom index, verify it implements the XML-RPC `search` method.","Check for proxy or TLS interception that could corrupt the XML-RPC response.","For programmatic package discovery, query https://pypi.org/simple/ or the PyPI JSON API (https://pypi.org/pypi/<name>/json)."],"exampleFix":"# before (broken on modern PyPI)\npip search requests\n# after: use the JSON API\ncurl -s https://pypi.org/pypi/requests/json | jq '.info.summary'","handlingStrategy":"fallback","validationCode":"import urllib.request, json\n\ndef search_pypi_json(name: str) -> dict:\n    # Reliable alternative to the deprecated XML-RPC search\n    with urllib.request.urlopen(f'https://pypi.org/pypi/{name}/json') as r:\n        return json.load(r)\n","typeGuard":null,"tryCatchPattern":"try:\n    subprocess.run(['pip', 'search', query], check=True)\nexcept subprocess.CalledProcessError:\n    # Fallback to the JSON API since PyPI XML-RPC search is deprecated\n    result = search_pypi_json(query)\n","preventionTips":["Migrate off pip search entirely; PyPI disabled the XML-RPC endpoint.","Use https://pypi.org/pypi/<name>/json for programmatic lookups.","Catch CalledProcessError and fall back to the JSON API."],"tags":["pip","search","xmlrpc","network","pypi","deprecated"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}