Skip to content

fix(redis): drop ssl_* kwargs when building a non-TLS async connection pool#34615

Open
devin-ai-integration[bot] wants to merge 1 commit into
litellm_internal_stagingfrom
litellm_fix_redis_ssl_kwargs
Open

fix(redis): drop ssl_* kwargs when building a non-TLS async connection pool#34615
devin-ai-integration[bot] wants to merge 1 commit into
litellm_internal_stagingfrom
litellm_fix_redis_ssl_kwargs

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • Non-TLS Redis cache writes crash with ssl_check_hostname
  • Budget/spend counter increments fail on plain Redis

How it solves it:

  • Strip ssl_* kwargs when the pool is non-TLS
  • Keep them when ssl is truthy (SSLConnection)

Relevant issues

Fixes #34614

Linear ticket

Pre-Submission checklist

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

Screenshots / Proof of Fix

Local plaintext Redis 7.4.9 (docker run -d --rm --name lit-redis -p 6379:6379 redis:7-alpine) and a proxy config carrying the same ssl_check_hostname the Admin UI cache settings form always posts:

litellm_settings:
  cache: true
  cache_params:
    type: redis
    host: localhost
    port: "6379"
    ssl: false
    ssl_check_hostname: false

Before, at 4ea58b7 with litellm/_redis.py reverted to its parent (git checkout HEAD~1 -- litellm/_redis.py):

$ curl -s http://localhost:4000/cache/ping -H "Authorization: Bearer sk-1234"
{"error":{"message":"{\"message\": \"Service Unhealthy\", ... \"redis_kwargs\": {\"host\": \"localhost\", \"port\": \"6379\", \"socket_timeout\": 5.0, \"ssl\": false, \"ssl_check_hostname\": false} ...","type":"cache_ping_error","param":"cache_ping","code":"503"}}

$ grep AbstractConnection litellm.log | head -1
LiteLLM:ERROR: redis_cache.py:1247 - LiteLLM Redis Cache PING: - Got exception from REDIS : AbstractConnection.__init__() got an unexpected keyword argument 'ssl_check_hostname'

After, at 4ea58b7:

$ curl -s http://localhost:4000/cache/ping -H "Authorization: Bearer sk-1234"
{"status":"healthy","cache_type":"redis","ping_response":true,"set_cache_response":"success", ... "redis_version":"7.4.9"}

Type

🐛 Bug Fix

Changes

get_redis_connection_pool consumes ssl and only swaps in async_redis.SSLConnection when it is truthy, but every other ssl_* option stayed in the kwargs that get handed to the pool's connection class. On a plaintext deployment those land on redis.asyncio.Connection, whose AbstractConnection.__init__ has no ssl_check_hostname, so every cache write and every spend-counter increment raises a TypeError; the proxy stays HTTP-healthy, which is why it shows up as silently broken caching rather than a startup failure. The Admin UI cache settings form always posts ssl_check_hostname, so a non-TLS setup hits this as soon as anything writes cache settings

if redis_kwargs.pop("ssl", None):
    redis_kwargs["connection_class"] = async_redis.SSLConnection
else:
    redis_kwargs = {k: v for k, v in redis_kwargs.items() if not k.startswith("ssl_")}

Two regression tests in tests/test_litellm/test_redis.py cover both directions: a plain pool must carry no ssl* connection kwargs and must be able to instantiate its connection class, and a TLS pool must still keep ssl_check_hostname / ssl_cert_reqs

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

Link to Devin session: https://app.devin.ai/sessions/780c6d9bd4bb456397e53592ec022e78

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@greptile-apps

greptile-apps Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR prevents TLS-only Redis options from reaching plaintext asynchronous connection pools.

  • Removes ssl_* kwargs when the pool uses the standard non-TLS connection class.
  • Preserves TLS options when ssl selects SSLConnection.
  • Adds regression coverage for both plaintext and TLS pool construction.

Confidence Score: 3/5

The string-valued false configuration path must be fixed before merging because it still selects TLS for plaintext Redis.

The new filtering only runs after the raw ssl value evaluates false; non-empty string representations such as "false" instead select SSLConnection, leaving plaintext cache connections unable to connect.

Files Needing Attention: litellm/_redis.py, tests/test_litellm/test_redis.py

Important Files Changed

Filename Overview
litellm/_redis.py Strips TLS-only options from the non-TLS pool path, but string-valued false settings still select the TLS path.
tests/test_litellm/test_redis.py Adds focused, network-free regression tests for plaintext and TLS options but does not cover a direct string "false" value.

Reviews (1): Last reviewed commit: "fix(redis): drop ssl_* kwargs when build..." | Re-trigger Greptile

Comment thread litellm/_redis.py
Comment on lines +693 to +694
else:
redis_kwargs = {k: v for k, v in redis_kwargs.items() if not k.startswith("ssl_")}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 String false still selects TLS

When a direct caller or an environment-backed secret supplies ssl="false", the raw truthiness check selects SSLConnection instead of entering this filtering branch, causing plaintext Redis connections to attempt TLS and fail or time out. Normalize string boolean values before choosing the connection class so the non-TLS fix covers this supported configuration path.

Knowledge Base Used: Response Caching

@codecov

codecov Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed-hq

codspeed-hq Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_fix_redis_ssl_kwargs (4ea58b7) with litellm_internal_staging (b9b27c2)

Open in CodSpeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Redis cache fails with unexpected ssl_check_hostname in v1.93.0

1 participant