imperugo/stackexchange.redis.extensions/diagnose
Claude Code and agent skill by imperugo/stackexchange.redis.extensions
- community
Checking that the SKILL.md file is still in the repository.
Troubleshoot common StackExchange.Redis.Extensions issues — timeouts, connection failures, serialization problems, pool exhaustion, distributed locks, Lua scripting
Install
npx vskill@latest install imperugo/stackexchange.redis.extensions/diagnoseSKILL.md
Redis Diagnose
Diagnose and fix common issues with StackExchange.Redis.Extensions.
When to use
When the user reports:
- Timeout exceptions
- Connection failures
- Serialization errors
- Pool exhaustion
- Pub/Sub messages not being received
- Distributed lock failures
- Lua scripting errors
- Performance issues
Diagnostic Tree
RedisTimeoutException
Symptoms: StackExchange.Redis.RedisTimeoutException
Check in order:
- SyncTimeout too low — default is 5000ms, increase for slow networks
``csharp config.SyncTimeout = 10000; // 10 seconds ``
- Pool size too small — default 5, increase for high-throughput
``csharp config.PoolSize = 10; ``
- Connection strategy — switch to LeastLoaded if using RoundRobin
``csharp config.ConnectionSelectionStrategy = ConnectionSelectionStrategy.LeastLoaded; ``
- Large values — enable compression to reduce payload size
``csharp services.AddRedisCompression<LZ4Compressor>(); ``
- ThreadPool starvation — check with
ThreadPool.GetAvailableThreads(), increase min threads
RedisConnectionException
Symptoms: SocketClosed, ConnectionFailed
Check:
- Redis server reachable? —
redis-cli -h <host> -p <port> ping - Firewall/NSG rules — port 6379 (or 6380 for TLS) open?
- TLS misconfiguration — if using Ssl=true, check certificate callbacks
- Sentinel misconfiguration — ServiceName must match Redis master name exactly
- Azure Cache for Redis — ensure Managed Identity is configured if not using password
Serialization Errors
Symptoms: JsonException, InvalidOperationException, corrupt data
Check:
- Type mismatch — GetAsync<T> must use same T as AddAsync<T>
- String values are JSON-encoded — "hello" is stored as "\"hello\"", this is by design
- Compression migration — enabling compression makes old (uncompressed) data unreadable
- Error:
InvalidOperationException: Failed to decompress data from Redis - Fix: flush the database or read old data without compression first
- Value type quirk —
GetAsync<int>()returns 0 (not null) for missing keys becausedefault(int)is0. UseGetAsync<int?>()to distinguish missing keys from actual zero values.
Pub/Sub Not Receiving Messages
Check:
- KeyPrefix — channels are automatically prefixed. Don't add prefix manually.
- Serializer mismatch — publisher and subscriber must use the same serializer
- Handler exceptions — check logs for EventId 4001 errors. Handlers that throw don't crash but the message is lost.
- Different connection pools — ensure pub and sub use the same IRedisDatabase instance
Pool Exhaustion / All Connections Down
Symptoms: All operations fail, logs show EventId 1003
Check:
- Pool health — inject
IRedisClientand callclient.ConnectionPoolManager.GetConnectionInformation() - Use health check — register
builder.Services.AddHealthChecks().AddRedisExtensionsHealthCheck()to monitor pool status automatically (returns Healthy/Degraded/Unhealthy) - Redis server overloaded — check
INFO clientson Redis - Network partition — the pool skips disconnected connections automatically and logs warnings
- Dispose pattern — ensure IRedisConnectionPoolManager is not disposed prematurely
IDistributedCache Issues
Symptoms: Data not found, expiration not working, migration issues
Check:
- Registration order —
AddRedisDistributedCache()must be called afterAddStackExchangeRedisExtensions<T>() - KeyPrefix applies — IDistributedCache goes through
IRedisDatabase.Databasewhich usesWithKeyPrefix. Cache keys are prefixed automatically. - Migration from Microsoft provider — hash schema is compatible (
data/absexp/sldexpfields), but key prefix format may differ (this library usesKeyPrefix, Microsoft usesInstanceName) - Sliding expiration not refreshing —
GetandRefreshboth refresh the TTL. Check thatSlidingExpirationwas set inDistributedCacheEntryOptions
Keyed DI Not Resolving
Symptoms: [FromKeyedServices("name")] returns null
Check:
- Config must have a Name —
RedisConfiguration.Namemust be non-empty for keyed registration - Use eager overloads — keyed services are only registered with the overloads that receive
RedisConfigurationdirectly, NOT theFunc<IServiceProvider, ...>overload - Name must match exactly —
[FromKeyedServices("cache")]must matchconfig.Name = "cache"(case-sensitive)
Distributed Lock Issues
Symptoms: Lock not acquired, deadlocks, lock lost during processing
Check:
- LockAcquireAsync returns null — increase
maxRetriesorretryDelay, the resource may be legitimately contended - Lock expires during processing — use
lockObj.ExtendAsync(TimeSpan)to extend the TTL before it expires - Lock not released on error — always use
await usingpattern, never try/finally with manual release - Deadlock — ensure lock expiry is always set. If the holder crashes, the lock auto-expires
- This is a single-instance lock — for Redis Cluster, consider Redlock algorithm
Lua Script Errors
Symptoms: RedisServerException, NOSCRIPT, wrong return type
Check:
- NOSCRIPT error — the script was cached but the server restarted. SE.Redis retries with EVAL automatically, but check for transient failures
- Wrong return type — Lua
return 1returnslong,return "hello"returnsstring. Use explicit casts on RedisResult - CROSSSLOT error in Cluster — all KEYS[] must hash to the same slot. Use hash tags:
{user}:counter,{user}:data - Script blocks Redis — Lua runs atomically, blocking the event loop. Keep scripts short (<1ms). Use read-only variant (
ScriptEvaluateReadOnlyAsync) for read operations to route to replicas - Typed deserialization fails —
ScriptEvaluateAsync<T>passes the raw bytes through ISerializer. Ensure the script returns a value serialized in the same format
Performance Issues
Check:
- Enable logging — set log level to Debug to see connection selection
``json { "Logging": { "LogLevel": { "StackExchange.Redis.Extensions.Core": "Debug" } } } ``
- Check outstanding commands — pool info shows outstanding count per connection
- Use compression for large objects — LZ4 adds ~1ms latency but reduces network 5-10x
- Use AddAllAsync for bulk writes instead of loop of AddAsync
- Use GetAllAsync for bulk reads (note: requires
HashSet<string>for keys, not arrays)
Logging Reference
| EventId | Level | Meaning | |
|---|---|---|---|
| 1001 | Info | Pool initialized successfully | |
| 1003 | Warning | All connections disconnected — degraded mode | |
| 1006 | Error | Pool initialization failed | |
| 2001 | Error | Connection failed | |
| 2002 | Warning | Connection restored | |
| 4001 | Error | Pub/Sub handler threw exception |
Enable with:
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingclaude-plugin/skills/diagnose/SKILL.md
Popularity
- Repository stars
- 625
- Repository forks
- 179
- 7-day trend score
- 32
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 8 Jun 2026, 4 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/imperugo/stackexchange.redis.extensions/diagnose)