{"record":{"id":"cbb0040b01a17b7d","repo":"redis/redis-py","slug":"redis-url-must-specify-one-of-the-following-scheme","errorCode":null,"errorMessage":"Redis URL must specify one of the following schemes (redis://, rediss://, unix://)","messagePattern":"Redis URL must specify one of the following schemes \\(redis://, rediss://, unix://\\)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/asyncio/connection.py","lineNumber":1773,"sourceCode":")\n\n\nclass ConnectKwargs(TypedDict, total=False):\n    username: str\n    password: str\n    connection_class: Type[AbstractConnection]\n    host: str\n    port: int\n    db: int\n    path: str\n\n\ndef parse_url(url: str) -> ConnectKwargs:\n    # Scheme names are case-insensitive (RFC 3986), so normalize before the\n    # prefix check; the \"://\" is required so a URL like \"redis:foo\" (which\n    # urlparse would still report as the \"redis\" scheme) is rejected.\n    if not url.lower().startswith((\"redis://\", \"rediss://\", \"unix://\")):\n        raise ValueError(\n            \"Redis URL must specify one of the following schemes \"\n            \"(redis://, rediss://, unix://)\"\n        )\n\n    parsed: ParseResult = urlparse(url)\n    kwargs: ConnectKwargs = {}\n\n    for name, value_list in parse_qs(parsed.query).items():\n        if value_list and len(value_list) > 0:\n            # parse_qs() already percent-decodes query values, so use the value\n            # as-is; unquoting again here would double-decode (e.g. \"%2520\" ->\n            # \"%20\" -> \" \"). See issue #4208.\n            value = value_list[0]\n            parser = URL_QUERY_ARGUMENT_PARSERS.get(name)\n            if parser:\n                try:\n                    kwargs[name] = parser(value)\n                except (TypeError, ValueError):","sourceCodeStart":1755,"sourceCodeEnd":1791,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/asyncio/connection.py#L1755-L1791","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)://."],"exampleFix":"// before\nr = redis.asyncio.from_url(os.environ['REDIS_URL'])  # value: 'host:6379'\n// after\nr = redis.asyncio.from_url('redis://' + os.environ['REDIS_URL'].strip())","handlingStrategy":"validation","validationCode":"import re\n\n_SCHEME = re.compile(r'^(redis|rediss|unix)://', re.IGNORECASE)\n\ndef require_redis_url(url: str) -> str:\n    if not _SCHEME.match(url.strip()):\n        raise ValueError('REDIS_URL must start with redis://, rediss://, or unix://')\n    return url.strip()","typeGuard":"def is_bad_scheme(exc: BaseException) -> bool:\n    return isinstance(exc, ValueError) and 'scheme' in str(exc).lower()","tryCatchPattern":"try:\n    r = redis.asyncio.from_url(url)\nexcept ValueError as e:\n    if 'scheme' in str(e).lower():\n        url = 'redis://' + url\n        r = redis.asyncio.from_url(url)\n    else:\n        raise","preventionTips":["Validate REDIS_URL with a regex at startup.","Strip whitespace from env vars.","Use secret/config managers that enforce the scheme prefix."],"tags":["url","config","validation","scheme","async"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}