redis/redis-py · error · ValueError
Redis URL must specify one of the following schemes…
Error message
Redis URL must specify one of the following schemes (redis://, rediss://, unix://)
What it means
Raised as ValueError from parse_url() when the URL (case-insensitively, after requiring the '://' separator) does not start with redis://, rediss://, or unix://. The check happens before any urlparse work, so malformed inputs fail fast. The error is raised during from_url() / connection-pool construction, before any network activity.
Solutions
- Prefix the value with redis:// (plain), rediss:// (TLS), or unix:// (UDS).
- Strip whitespace/newlines from env vars before passing to from_url.
- Validate the URL at app startup with a regex like ^(redis|rediss|unix)://.
Example fix
// before
r = redis.asyncio.from_url(os.environ['REDIS_URL']) # value: 'host:6379'
// after
r = redis.asyncio.from_url('redis://' + os.environ['REDIS_URL'].strip()) Defensive patterns
Strategy: validation
Validate before calling
import re
_SCHEME = re.compile(r'^(redis|rediss|unix)://', re.IGNORECASE)
def require_redis_url(url: str) -> str:
if not _SCHEME.match(url.strip()):
raise ValueError('REDIS_URL must start with redis://, rediss://, or unix://')
return url.strip() Type guard
def is_bad_scheme(exc: BaseException) -> bool:
return isinstance(exc, ValueError) and 'scheme' in str(exc).lower() Try / catch
try:
r = redis.asyncio.from_url(url)
except ValueError as e:
if 'scheme' in str(e).lower():
url = 'redis://' + url
r = redis.asyncio.from_url(url)
else:
raise Prevention
- Validate REDIS_URL with a regex at startup.
- Strip whitespace from env vars.
- Use secret/config managers that enforce the scheme prefix.
When it happens
Trigger: Calling redis.asyncio.from_url(...) with a missing scheme ('localhost:6379'), a wrong scheme ('http://', 'tcp://'), or a scheme with no '://' like 'redis:foo' (explicitly rejected to avoid a urlparse false-positive).
Common situations: Env var missing the scheme; templated config producing 'redis://' + '' (empty host) or a leading space; copy-pasting a TCP URL into a redis:// field; using rediss for TLS but missing an 's'; trailing whitespace.
Related errors
- Invalid ssl verify flag
- Invalid value for ' ' in connection URL.
- Invalid SSL Certificate Requirements Flag
- Maintenance notifications are not supported for connection…
- Maintenance notifications are not supported for connections…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/cbb0040b01a17b7d.
Report an issue: GitHub.
Appendix: source
Thrown at redis/asyncio/connection.py:1773
)
class ConnectKwargs(TypedDict, total=False):
username: str
password: str
connection_class: Type[AbstractConnection]
host: str
port: int
db: int
path: str
def parse_url(url: str) -> ConnectKwargs:
# Scheme names are case-insensitive (RFC 3986), so normalize before the
# prefix check; the "://" is required so a URL like "redis:foo" (which
# urlparse would still report as the "redis" scheme) is rejected.
if not url.lower().startswith(("redis://", "rediss://", "unix://")):
raise ValueError(
"Redis URL must specify one of the following schemes "
"(redis://, rediss://, unix://)"
)
parsed: ParseResult = urlparse(url)
kwargs: ConnectKwargs = {}
for name, value_list in parse_qs(parsed.query).items():
if value_list and len(value_list) > 0:
# parse_qs() already percent-decodes query values, so use the value
# as-is; unquoting again here would double-decode (e.g. "%2520" ->
# "%20" -> " "). See issue #4208.
value = value_list[0]
parser = URL_QUERY_ARGUMENT_PARSERS.get(name)
if parser:
try:
kwargs[name] = parser(value)
except (TypeError, ValueError):View on GitHub (pinned to 6a6b581b48)