{"record":{"id":"e2c779e5d3bc0ed0","repo":"pypa/pip","slug":"trusted-host-url-must-include-a-host-part-host-r","errorCode":null,"errorMessage":"Trusted host URL must include a host part: {host!r}","messagePattern":"Trusted host URL must include a host part: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/network/session.py","lineNumber":426,"sourceCode":"\n    def add_trusted_host(\n        self, host: str, source: str | None = None, suppress_logging: bool = False\n    ) -> None:\n        \"\"\"\n        :param host: It is okay to provide a host that has previously been\n            added.\n        :param source: An optional source string, for logging where the host\n            string came from.\n        \"\"\"\n        if not suppress_logging:\n            msg = f\"adding trusted host: {host!r}\"\n            if source is not None:\n                msg += f\" (from {source})\"\n            logger.info(msg)\n\n        parsed_host, parsed_port = parse_netloc(host)\n        if parsed_host is None:\n            raise ValueError(f\"Trusted host URL must include a host part: {host!r}\")\n        if (parsed_host, parsed_port) not in self.pip_trusted_origins:\n            self.pip_trusted_origins.append((parsed_host, parsed_port))\n\n        self.mount(\n            build_url_from_netloc(host, scheme=\"http\") + \"/\", self._trusted_host_adapter\n        )\n        self.mount(build_url_from_netloc(host) + \"/\", self._trusted_host_adapter)\n        if not parsed_port:\n            self.mount(\n                build_url_from_netloc(host, scheme=\"http\") + \":\",\n                self._trusted_host_adapter,\n            )\n            # Mount wildcard ports for the same host.\n            self.mount(build_url_from_netloc(host) + \":\", self._trusted_host_adapter)\n\n    def iter_secure_origins(self) -> Generator[SecureOrigin, None, None]:\n        yield from SECURE_ORIGINS\n        for host, port in self.pip_trusted_origins:","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/network/session.py#L408-L444","documentation":"Raised as a ValueError by PipSession.add_trusted_host when parse_netloc(host) returns None for the host component, i.e. the --trusted-host value (or a trusted-host entry from pip.conf) has no parseable hostname. A trusted host must carry at least a host part.","triggerScenarios":"Passing pip --trusted-host with a port-only or path-only or empty string (e.g. ':8080', '/path', 'http://'), or a malformed trusted-host line in config, so parse_netloc yields no host.","commonSituations":"Typo in --trusted-host; copy-pasting a URL fragment instead of a host; config automation that emits an empty trusted-host value; trailing slashes or scheme-only strings.","solutions":["Provide a hostname: --trusted-host pypi.org or --trusted-host my.server:8080.","If using a full URL, ensure it contains a host, e.g. http://my.server.","Audit pip.conf / requirements for malformed trusted-host entries."],"exampleFix":"# before\npip install --trusted-host \":8080\" pkg\n\n# after\npip install --trusted-host my.server:8080 pkg","handlingStrategy":"validation","validationCode":"from urllib.parse import urlsplit\n\ndef trusted_host_has_host(host: str) -> bool:\n    parsed = host if \"://\" in host else f\"//{host}\"\n    return urlsplit(parsed, allow_fragments=False).hostname is not None\n\n# assert trusted_host_has_host(\"pypi.org\")\n# assert not trusted_host_has_host(\":8080\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include a hostname in --trusted-host values.","Validate trusted-host entries before writing them to pip.conf.","Avoid passing paths or port-only strings as trusted hosts."],"tags":["cli","trusted-host","url-parsing","configuration"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}