psf/requests · error · InvalidSchema
No connection adapters were found for {url!r}
Error message
No connection adapters were found for {url!r} What it means
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.
Source
Thrown at src/requests/sessions.py:881
proxies = merge_setting(proxies, self.proxies)
stream = merge_setting(stream, self.stream)
verify = merge_setting(verify, self.verify)
cert = merge_setting(cert, self.cert)
return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert}
def get_adapter(self, url: str) -> BaseAdapter:
"""
Returns the appropriate connection adapter for the given URL.
:rtype: requests.adapters.BaseAdapter
"""
for prefix, adapter in self.adapters.items():
if url.lower().startswith(prefix.lower()):
return adapter
# Nothing matches :-/
raise InvalidSchema(f"No connection adapters were found for {url!r}")
def close(self) -> None:
"""Closes all adapters and as such the session"""
for v in self.adapters.values():
v.close()
def mount(self, prefix: str, adapter: BaseAdapter) -> None:
"""Registers a connection adapter to a prefix.
Adapters are sorted in descending order by prefix length.
"""
self.adapters[prefix] = adapter
keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]
for key in keys_to_move:
self.adapters[key] = self.adapters.pop(key)
def __getstate__(self) -> dict[str, Any]:View on GitHub ↗ (pinned to 414f0513c3)
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.
Example fix
# before
base = os.environ['API_HOST'] # 'api.example.com'
requests.get(f'{base}/v1/items')
# after
base = os.environ['API_HOST']
if not base.startswith(('http://', 'https://')):
base = 'https://' + base
requests.get(f'{base}/v1/items') Defensive patterns
Strategy: validation
Validate before calling
def has_adapter(session, url):
return any(url.lower().startswith(prefix) for prefix in session.adapters)
if not has_adapter(session, url):
raise ValueError(f'No adapter mounted for {url!r} — expected http:// or https://') Try / catch
try:
resp = session.get(url)
except requests.exceptions.InvalidSchema as e:
# scheme like ftp://, file://, ws:// or a missing scheme entirely
log.error('Unsupported URL scheme: %s', e) Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid URL {url!r}: No scheme supplied. Perhaps you meant h
- Invalid URL {url!r}: No host supplied
- URL has an invalid label.
- Invalid percent-escape sequence: '{h}'
- Files must be provided.
AI-assisted analysis of psf/requests@414f0513c3 (2026-07-31).
Data as JSON: /data/errors/8b7d06f4fad34a22.json.
Report an issue: GitHub ↗.