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

  1. Prefix the value with redis:// (plain), rediss:// (TLS), or unix:// (UDS).
  2. Strip whitespace/newlines from env vars before passing to from_url.
  3. 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

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


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)