chroma-core/chroma · error · ValueError
Invalid URL. Unrecognized protocol - {parsed.scheme}.
Error message
Invalid URL. Unrecognized protocol - {parsed.scheme}. What it means
Host validation in BaseHTTPClient.resolve_url(): the host string contains a '/' and urlparse() extracted a scheme that is not http or https. Chroma accepts either a bare hostname/IP or a full http(s):// URL; anything else with a slash is rejected. Notably, urlparse('localhost:8000/api') yields scheme 'localhost', so passing host:port/path as the host trips this exact branch with "Unrecognized protocol - localhost".
Source
Thrown at chromadb/api/base_http_client.py:54
max_connections = self._settings.chroma_http_max_connections
if max_connections is not None:
limit_kwargs["max_connections"] = max_connections
max_keepalive_connections = self._settings.chroma_http_max_keepalive_connections
if max_keepalive_connections is not None:
limit_kwargs["max_keepalive_connections"] = max_keepalive_connections
return httpx.Limits(**limit_kwargs)
@property
def http_limits(self) -> httpx.Limits:
return self._http_limits
@staticmethod
def _validate_host(host: str) -> None:
parsed = urlparse(host)
if "/" in host and parsed.scheme not in {"http", "https"}:
raise ValueError(
"Invalid URL. " f"Unrecognized protocol - {parsed.scheme}."
)
if "/" in host and (not host.startswith("http")):
raise ValueError(
"Invalid URL. "
"Seems that you are trying to pass URL as a host but without \
specifying the protocol. "
"Please add http:// or https:// to the host."
)
@staticmethod
def resolve_url(
chroma_server_host: str,
chroma_server_ssl_enabled: Optional[bool] = False,
default_api_path: Optional[str] = "",
chroma_server_http_port: Optional[int] = 8000,
) -> str:
_skip_port = FalseView on GitHub (pinned to aecdd12c8a)
Solutions
- Pass a bare hostname and use the port argument: HttpClient(host="localhost", port=8000).
- If you intend to pass a full URL, prefix it with http:// or https:// (e.g. host="http://localhost:8000").
- Move any API path out of the host — the client builds the path itself.
Example fix
# before client = HttpClient(host="localhost:8000/api/v2") # ValueError: Unrecognized protocol - localhost # after client = HttpClient(host="localhost", port=8000)
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def valid_chroma_host(host: str) -> bool:
parsed = urlparse(host)
return "/" not in host or parsed.scheme in {"http", "https"}
assert valid_chroma_host("localhost:8000/api") is False # would raise in the client
assert valid_chroma_host("localhost") is True Try / catch
try:
client = chromadb.HttpClient(host=host, port=port)
except ValueError as e: # raised from resolve_url host validation
raise ValueError(f"Fix the host setting {host!r}: {e}") from e Prevention
- Keep host to a bare hostname/IP; pass the port separately.
- Lint config: reject host values containing '/' unless they start with http(s)://.
- Use dedicated CHROMA_SERVER_HOST/CHROMA_SERVER_PORT variables rather than one URL string.
When it happens
Trigger: HttpClient(host="localhost:8000/api/v2") — the port belongs in the port argument; host="ftp://box" or host="tcp://box"; any scheme-prefixed string other than http/https.
Common situations: Pasting a URL copied from docs or a browser into the host parameter; migrating config from another SDK that takes a full DSN; putting the API path in the host.
Related errors
- Invalid URL. Seems that you are trying to pass URL as a host
- Embedding function provided when already defined in the coll
- not a valid space: {space_value}
- Cannot update embedding function: incompatible types ({exist
- Multiple embedding functions provided. Please provide only o
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/e343d82b22f1fb85.
Report an issue: GitHub.