{"record":{"id":"e3bcf06e973a9252","repo":"BerriAI/litellm","slug":"either-host-or-url-must-be-specified-for-redis","errorCode":null,"errorMessage":"Either 'host' or 'url' must be specified for redis.","messagePattern":"Either 'host' or 'url' must be specified for redis\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/_redis.py","lineNumber":483,"sourceCode":"\n    if \"url\" in redis_kwargs and redis_kwargs[\"url\"] is not None:\n        # Only strip host/port/db/password when not routing to a cluster.\n        # When startup_nodes is also present the cluster path takes priority and\n        # needs the password for authentication.\n        if not redis_kwargs.get(\"startup_nodes\"):\n            redis_kwargs.pop(\"host\", None)\n            redis_kwargs.pop(\"port\", None)\n            redis_kwargs.pop(\"db\", None)\n            redis_kwargs.pop(\"password\", None)\n    elif (\n        \"startup_nodes\" in redis_kwargs\n        and redis_kwargs[\"startup_nodes\"] is not None\n        or \"sentinel_nodes\" in redis_kwargs\n        and redis_kwargs[\"sentinel_nodes\"] is not None\n    ):\n        pass\n    elif \"host\" not in redis_kwargs or redis_kwargs[\"host\"] is None:\n        raise ValueError(\"Either 'host' or 'url' must be specified for redis.\")\n\n    # litellm.print_verbose(f\"redis_kwargs: {redis_kwargs}\")\n    return redis_kwargs\n\n\ndef init_redis_cluster(redis_kwargs) -> redis.RedisCluster:\n    _redis_cluster_nodes_in_env: Final[str | None] = get_secret(\"REDIS_CLUSTER_NODES\")\n    if _redis_cluster_nodes_in_env is not None:\n        try:\n            redis_kwargs[\"startup_nodes\"] = json.loads(_redis_cluster_nodes_in_env)\n        except json.JSONDecodeError:\n            raise ValueError(\n                \"REDIS_CLUSTER_NODES environment variable is not valid JSON. Please ensure it's properly formatted.\"\n            )\n\n    verbose_logger.debug(\"init_redis_cluster: startup nodes are being initialized.\")\n    from redis.cluster import ClusterNode\n","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/_redis.py#L465-L501","documentation":"In litellm/_redis.py's kwargs normalization (the function returning redis_kwargs for cache init): if 'url' is provided, host/port/db/password are stripped; elif startup_nodes or sentinel_nodes are present, host is not required; otherwise host must be present — ValueError(\"Either 'host' or 'url' must be specified for redis.\") when the caller passed neither.","triggerScenarios":"Constructing RedisCache(...) or configuring cache in the proxy with only port/password/namespace but no host and no url; passing host=None explicitly; a config template where the host placeholder was left empty; for cluster use, intending startup_nodes but misspelling the key so it falls through to the host check.","commonSituations":"YAML cache config with cache: type: redis and incomplete redis_settings; copy-paste of RedisCache examples that rely on env vars while also passing partial kwargs; typos like startup_node (singular) bypassing the cluster branch.","solutions":["Pass url=... (redis:// or rediss://...) to RedisCache / redis_settings","Or pass host= (and port=) explicitly","For cluster mode, pass startup_nodes=[{\"host\": ..., \"port\": ...}] (correctly spelled) so the host requirement is waived","For sentinel, pass sentinel_nodes=... (handled by the sentinel initializer)"],"exampleFix":"# before\nRedisCache(port=6379, password=\"x\")  # no host, no url -> ValueError\n\n# after\nRedisCache(host=\"redis.internal\", port=6379, password=\"x\")\n# or\nRedisCache(url=\"redis://:x@redis.internal:6379/0\")","handlingStrategy":"validation","validationCode":"def validate_redis_kwargs(kwargs: dict) -> None:\n    has_url = bool(kwargs.get(\"url\"))\n    has_host = bool(kwargs.get(\"host\"))\n    has_nodes = bool(kwargs.get(\"startup_nodes\") or kwargs.get(\"sentinel_nodes\"))\n    if not (has_url or has_host or has_nodes):\n        raise ValueError(\n            \"Redis misconfigured: provide url=..., host=..., startup_nodes=..., or sentinel_nodes=...\"\n        )","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make url the canonical way to configure Redis in your YAML/JSON config schemas","Validate cache settings with a schema/lint step before deploying the proxy","For clusters/sentinels, double-check key spelling (startup_nodes, sentinel_nodes) — typos fall through to the host check"],"tags":["redis","configuration","cache","validation","startup"],"backgroundTag":"missing-configuration","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}