{"id":"8b7d06f4fad34a22","repo":"psf/requests","slug":"no-connection-adapters-were-found-for-url-r","errorCode":null,"errorMessage":"No connection adapters were found for {url!r}","messagePattern":"No connection adapters were found for (.+?)","errorType":"exception","errorClass":"InvalidSchema","httpStatus":null,"severity":"error","filePath":"src/requests/sessions.py","lineNumber":881,"sourceCode":"        proxies = merge_setting(proxies, self.proxies)\n        stream = merge_setting(stream, self.stream)\n        verify = merge_setting(verify, self.verify)\n        cert = merge_setting(cert, self.cert)\n\n        return {\"proxies\": proxies, \"stream\": stream, \"verify\": verify, \"cert\": cert}\n\n    def get_adapter(self, url: str) -> BaseAdapter:\n        \"\"\"\n        Returns the appropriate connection adapter for the given URL.\n\n        :rtype: requests.adapters.BaseAdapter\n        \"\"\"\n        for prefix, adapter in self.adapters.items():\n            if url.lower().startswith(prefix.lower()):\n                return adapter\n\n        # Nothing matches :-/\n        raise InvalidSchema(f\"No connection adapters were found for {url!r}\")\n\n    def close(self) -> None:\n        \"\"\"Closes all adapters and as such the session\"\"\"\n        for v in self.adapters.values():\n            v.close()\n\n    def mount(self, prefix: str, adapter: BaseAdapter) -> None:\n        \"\"\"Registers a connection adapter to a prefix.\n\n        Adapters are sorted in descending order by prefix length.\n        \"\"\"\n        self.adapters[prefix] = adapter\n        keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]\n\n        for key in keys_to_move:\n            self.adapters[key] = self.adapters.pop(key)\n\n    def __getstate__(self) -> dict[str, Any]:","sourceCodeStart":863,"sourceCodeEnd":899,"githubUrl":"https://github.com/psf/requests/blob/414f0513c33883adf6f2b46901d4f0b38a455851/src/requests/sessions.py#L863-L899","documentation":"Raised as `requests.exceptions.InvalidSchema` from `Session.get_adapter()` in `src/requests/sessions.py:881`. A Session dispatches each URL to a transport adapter chosen by longest matching prefix; by default only 'http://' and 'https://' adapters are mounted. If the request URL matches no mounted prefix (unknown scheme, missing scheme, or a typo), there is no transport capable of sending it.","triggerScenarios":"Calling `requests.get('example.com/path')` (no scheme), a typo like 'htp://' or 'https:/', a non-HTTP scheme such as 'ftp://', 'file://', 'ws://', 'localhost:8000/api' (parsed as scheme 'localhost'), or a URL with leading whitespace/quotes so the prefix match fails.","commonSituations":"URLs from config files or env vars stored without the scheme; concatenation bugs producing double or missing slashes; pasting a URL wrapped in quotes; expecting requests to fetch file:// or ftp:// resources (unsupported without a third-party adapter like requests-file/requests-ftp); base-URL joining that drops the scheme.","solutions":["Add the scheme: use 'https://example.com/path'; the repr in the message shows the exact URL requests saw — check it for missing scheme, typos, whitespace, or quote characters.","If the URL comes from config, normalize it: `url if url.startswith(('http://','https://')) else 'https://' + url`.","For non-HTTP schemes, mount an adapter that supports them (e.g. `requests_file.FileAdapter` for file://) or use the appropriate library (ftplib, websockets).","Strip stray characters: `url.strip().strip('\\'\"')` before requesting."],"exampleFix":"# before\nbase = os.environ['API_HOST']  # 'api.example.com'\nrequests.get(f'{base}/v1/items')\n# after\nbase = os.environ['API_HOST']\nif not base.startswith(('http://', 'https://')):\n    base = 'https://' + base\nrequests.get(f'{base}/v1/items')","handlingStrategy":"validation","validationCode":"def has_adapter(session, url):\n    return any(url.lower().startswith(prefix) for prefix in session.adapters)\n\nif not has_adapter(session, url):\n    raise ValueError(f'No adapter mounted for {url!r} — expected http:// or https://')","typeGuard":null,"tryCatchPattern":"try:\n    resp = session.get(url)\nexcept requests.exceptions.InvalidSchema as e:\n    # scheme like ftp://, file://, ws:// or a missing scheme entirely\n    log.error('Unsupported URL scheme: %s', e)","preventionTips":["Ensure URLs include an http:// or https:// scheme — a bare 'example.com' has no adapter","Validate/normalize user-supplied URLs with urllib.parse.urlparse and whitelist schemes at the boundary","Mount a custom adapter (session.mount('scheme://', adapter)) if you genuinely need a non-HTTP scheme","Watch for accidental schemes from copy-paste (ftp://, file://) in config-driven URLs"],"tags":["url","scheme","adapter","invalid-schema","python","requests"],"analyzedSha":"414f0513c33883adf6f2b46901d4f0b38a455851","analyzedAt":"2026-07-31T19:24:57.696Z","schemaVersion":2}