{
  "schema_version": 2,
  "id": "develop/clients/error-handling",
  "title": "Error handling",
  "url": "https://redis.io/docs/latest/develop/clients/error-handling/",
  "summary": "Learn how to handle errors when using Redis client libraries.",
  "tags": [],
  "last_updated": "2026-09-09T13:53:13+01:00",
  "page_type": "content",
  "content_hash": "a15bc7ba6a6cd3827537ebbd5c92707a202ef20bb106686be3c4c0fff1113811",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "When working with Redis, errors can occur for various reasons, including network issues, invalid commands, or resource constraints. This guide explains the types of errors you might encounter and how to handle them effectively."
    },
    {
      "id": "categories-of-errors",
      "title": "Categories of errors",
      "role": "content",
      "text": "Redis errors fall into four main categories. The table below provides a quick overview of each type. Click on any error type to jump to its detailed section, which includes common causes, examples, handling strategies, and code examples.\n\n| Error Type | Common Causes | When to Handle | Examples |\n|---|---|---|---|\n| [Connection errors](#connection-errors) | Network issues, server down, auth failure, timeouts, pool exhaustion | Almost always | `ConnectionError`, `TimeoutError`, `AuthenticationError` |\n| [Command errors](#command-errors) | Typo in command, wrong arguments, invalid types, unsupported command | Rarely (usually indicates a bug) | `ResponseError`, `WRONGTYPE`, `ERR unknown command` |\n| [Data errors](#data-errors) | Serialization failures, corrupted data, type mismatches | Sometimes (depends on data source) | `JSONDecodeError`, `SerializationError`, `WRONGTYPE` |\n| [Resource errors](#resource-errors) | Memory limit, pool exhausted, too many connections, key eviction | Sometimes (some are temporary) | `OOM`, pool timeout, `LOADING` |"
    },
    {
      "id": "connection-errors",
      "title": "Connection errors",
      "role": "content",
      "text": "Connection errors occur when your application cannot communicate with Redis. These are typically temporary and often recoverable.\n\n**Common causes:**\n- Network connectivity issues\n- Redis server is down or unreachable\n- Authentication failure\n- Connection timeout\n- Connection pool exhaustion\n\n**Examples:**\n- `ConnectionError`: Network failure or server unreachable\n- `TimeoutError`: Operation exceeded the configured timeout\n- `AuthenticationError`: Invalid credentials\n\n**When to handle:** Almost always. Connection errors are usually temporary, so implementing retry logic or fallback strategies is recommended.\n\n**Example strategy:**\n\n[code example]"
    },
    {
      "id": "command-errors",
      "title": "Command errors",
      "role": "syntax",
      "text": "Command errors occur when Redis receives an invalid or malformed command. These typically indicate a bug in your code.\n\n**Common causes:**\n-   Typo in command name\n-   Wrong number of arguments\n-   Invalid argument types (for example, supplying a\n    [string](https://redis.io/docs/latest/develop/data-types/strings) key to a\n    [list](https://redis.io/docs/latest/develop/data-types/lists) command))\n-   Using a command that doesn't exist in your Redis version\n\n**Examples:**\n- `ResponseError`: Invalid command or syntax error\n- `WRONGTYPE Operation against a key holding the wrong kind of value`\n- `ERR unknown command`\n\n**When to handle:** Rarely. These usually indicate programming error and so you\nshould fix the errors in your code rather than attempt to handle them at runtime. However, some cases (like invalid user input) may be worth handling.\n\n**Example:**\n\n[code example]"
    },
    {
      "id": "data-errors",
      "title": "Data errors",
      "role": "content",
      "text": "Data errors occur when there are problems with the data itself, such as\nserialization failures, or data corruption.\n\n**Common causes:**\n- Object cannot be serialized to JSON\n- Cached data is corrupted\n- Attempting to deserialize invalid data\n\n**Examples:**\n- `JSONDecodeError`: Cannot deserialize JSON data\n- `SerializationError`: Cannot serialize object\n\n**When to handle:** Sometimes. If the error is due to user input or external data, handle it gracefully. If it's due to your code, fix the code.\n\n**Example:**\n\n[code example]"
    },
    {
      "id": "resource-errors",
      "title": "Resource errors",
      "role": "content",
      "text": "Resource errors occur when Redis runs out of resources or hits limits.\n\n**Common causes:**\n- Memory limit reached\n- Connection pool exhausted\n- Too many connections\n- Key eviction due to memory pressure\n\n**Examples:**\n- `OOM command not allowed when used memory > 'maxmemory'`\n- Connection pool timeout\n- `LOADING Redis is loading the dataset in memory`\n\n**When to handle:** Sometimes. Some resource errors are temporary (Redis loading), while others indicate a configuration problem.\n\n**Example:**\n\n[code example]"
    },
    {
      "id": "error-handling-patterns",
      "title": "Error handling patterns",
      "role": "errors",
      "text": ""
    },
    {
      "id": "pattern-1-fail-fast",
      "title": "Pattern 1: Fail fast",
      "role": "content",
      "text": "Use this when the error is unrecoverable or indicates a bug in your code.\n\n**When to use:**\n\n- Command errors (invalid syntax)\n- Authentication errors\n- Programming errors\n\n**Example:**\n\n[code example]"
    },
    {
      "id": "pattern-2-graceful-degradation",
      "title": "Pattern 2: Graceful degradation",
      "role": "content",
      "text": "Use this when you have an alternative way to get the data you need, so you can\nfall back to using the alternative instead of the preferred code.\n\n**When to use:**\n\n- Cache reads (fallback to database)\n- Session reads (fallback to default values)\n- Optional data (skip if unavailable)\n\n**Example:**\n\n[code example]"
    },
    {
      "id": "pattern-3-retry-with-backoff",
      "title": "Pattern 3: Retry with backoff",
      "role": "content",
      "text": "Use this when the error could be due to network load or other temporary\nconditions.\n\n**When to use:**\n\n- Connection timeouts\n- Temporary network issues\n- Redis loading data\n\n**Example:**\n\n[code example]\n\nNote that client libraries often implement retry logic for you, so\nyou may just need to provide the right configuration rather than\nimplementing retries yourself. See [Client-specific error handling](#client-specific-error-handling) below for links to pages that\ndescribe retry configuration for each client library."
    },
    {
      "id": "pattern-4-log-and-continue",
      "title": "Pattern 4: Log and continue",
      "role": "content",
      "text": "Use this when the operation is not critical to your application.\n\n**When to use:**\n\n- Cache writes (data loss is acceptable)\n- Non-critical updates\n- Metrics collection\n\n**Example:**\n\n[code example]"
    },
    {
      "id": "decision-tree-how-to-handle-errors",
      "title": "Decision tree: How to handle errors",
      "role": "content",
      "text": "[code example]"
    },
    {
      "id": "logging-and-monitoring",
      "title": "Logging and monitoring",
      "role": "content",
      "text": "In production, you may find it useful to log errors when they\noccur and monitor the logs for patterns. This can help you identify\nwhich errors are most common and whether your retry and fallback\nstrategies are effective. Note that some Redis client\nlibraries have built-in instrumentation that can provide this\ninformation for you (see [Observability](https://redis.io/docs/latest/develop/clients/observability)\nfor a full description)."
    },
    {
      "id": "what-to-log",
      "title": "What to log",
      "role": "content",
      "text": "- **Error type and message:** What went wrong?\n- **Context:** Which key? Which operation?\n- **Timestamp:** When did it happen?\n- **Retry information:** Is this a retry? How many attempts?\n\n**Example:**\n[code example]"
    },
    {
      "id": "what-to-monitor",
      "title": "What to monitor",
      "role": "content",
      "text": "- **Error rate:** How many errors per minute?\n- **Error types:** Which errors are most common?\n- **Recovery success:** How many retries succeed?\n- **Fallback usage:** How often do we use fallback strategies?\n\nThese metrics help you identify patterns and potential issues."
    },
    {
      "id": "common-mistakes",
      "title": "Common mistakes",
      "role": "content",
      "text": ""
    },
    {
      "id": "catching-all-exceptions",
      "title": "Catching all exceptions",
      "role": "content",
      "text": "**Problem:** If you catch all exceptions, you might catch unexpected\nerrors and hide bugs.\n\n**Example (wrong):**\n\n[code example]\n\n**Better approach:** Catch specific exception types.\n\n**Example (correct):**\n\n[code example]"
    },
    {
      "id": "not-distinguishing-error-types",
      "title": "Not distinguishing error types",
      "role": "content",
      "text": "**Problem:** Different errors need different handling. For example, retrying a syntax error won't help.\n\n**Example (wrong):**\n\n[code example]\n\n**Better approach:** Handle each error type differently based on whether or not\nit is recoverable.\n\n**Example (correct):**\n\n[code example]"
    },
    {
      "id": "ignoring-connection-pool-errors",
      "title": "Ignoring connection pool errors",
      "role": "content",
      "text": "**Problem:** Connection pool errors indicate a configuration or concurrency issue that needs to be addressed.\n\n**Example (wrong):**\n\n[code example]\n\n**Better approach:** Monitor pool usage and increase size if needed."
    },
    {
      "id": "client-specific-error-handling",
      "title": "Client-specific error handling",
      "role": "content",
      "text": "For detailed information about exceptions in your client library, see:\n\n- [redis-py error handling](https://redis.io/docs/latest/develop/clients/redis-py/error-handling)\n- [Node.js error handling](https://redis.io/docs/latest/develop/clients/nodejs/error-handling)\n- [Java (Jedis) error handling](https://redis.io/docs/latest/develop/clients/jedis/error-handling)\n- [Java (Lettuce) error handling](https://redis.io/docs/latest/develop/clients/lettuce/error-handling)\n- [Go (go-redis) error handling](https://redis.io/docs/latest/develop/clients/go/error-handling)\n- [.NET (StackExchange.Redis) error handling](https://redis.io/docs/latest/develop/clients/dotnet/error-handling)\n- [PHP (Predis) error handling](https://redis.io/docs/latest/develop/clients/php/error-handling)\n- [Ruby (redis-rb) error handling](https://redis.io/docs/latest/develop/clients/ruby/error-handling)"
    }
  ],
  "examples": [
    {
      "id": "connection-errors-ex0",
      "language": "mermaid {width=\"80%\"}",
      "code": "graph TB\n    A[\"Try to connect<br/>to Redis\"]\n    A -->|Success| B([\"Use the result\"])\n    A -->|Failure| C{Error type?}\n    C -->|Timeout| D([\"Retry with<br/>exponential backoff\"])\n    C -->|Auth failure| E([\"Check credentials<br/>and fail\"])\n    C -->|Network error| F([\"Fallback to<br/>alternative data source\"])",
      "section_id": "connection-errors"
    },
    {
      "id": "command-errors-ex0",
      "language": "mermaid {width=\"60%\"}",
      "code": "graph TB\n    A[\"User provides<br/>JSONPath expression\"]\n    A --> B[\"Try to execute it\"]\n    direction TB\n    B -->|ResponseError| C[\"Log the error\"]\n    C --> D([\"Return default value<br/>or error message to user\"])\n    B -->|Success| E([\"Use the result\"])",
      "section_id": "command-errors"
    },
    {
      "id": "data-errors-ex0",
      "language": "mermaid {width=\"50%\"}",
      "code": "graph TB\n    A[\"Read cached data\"]\n    A --> B[\"Try to deserialize\"]\n    B -->|Success| C([\"Use the data\"])\n    B -->|Deserialization fails| D[\"Log the error\"]\n    D --> E[\"Delete corrupted<br/>cache entry\"]\n    E --> F([\"Fetch fresh data<br/>from source\"])",
      "section_id": "data-errors"
    },
    {
      "id": "resource-errors-ex0",
      "language": "mermaid {width=\"80%\"}",
      "code": "graph TB\n    A{Resource error<br/>occurred?}\n    A -->|Redis loading| B([\"Retry after<br/>a delay\"])\n    A -->|Memory full| C([\"Check Redis<br/>configuration and data\"])\n    A -->|Pool exhausted| D([\"Increase pool size<br/>or reduce concurrency\"])",
      "section_id": "resource-errors"
    },
    {
      "id": "pattern-1-fail-fast-ex0",
      "language": "python",
      "code": "try:\n    result = r.get(key)\nexcept redis.ResponseError as e:\n    # This indicates a bug in our code\n    raise  # Re-raise the exception",
      "section_id": "pattern-1-fail-fast"
    },
    {
      "id": "pattern-2-graceful-degradation-ex0",
      "language": "python",
      "code": "try:\n    cached_value = r.get(key)\n    if cached_value:\n        return cached_value\nexcept redis.ConnectionError:\n    logger.warning(\"Cache unavailable, using database\")\n\n# Fallback to database\nreturn database.get(key)",
      "section_id": "pattern-2-graceful-degradation"
    },
    {
      "id": "pattern-3-retry-with-backoff-ex0",
      "language": "python",
      "code": "import time\n\nmax_retries = 3\nretry_delay = 0.1\n\nfor attempt in range(max_retries):\n    try:\n        return r.get(key)\n    except redis.TimeoutError:\n        if attempt < max_retries - 1:\n            time.sleep(retry_delay)\n            retry_delay *= 2  # Exponential backoff\n        else:\n            raise",
      "section_id": "pattern-3-retry-with-backoff"
    },
    {
      "id": "pattern-4-log-and-continue-ex0",
      "language": "python",
      "code": "try:\n    r.setex(key, 3600, value)\nexcept redis.ConnectionError:\n    logger.warning(f\"Failed to cache {key}, continuing without cache\")\n    # Application continues normally",
      "section_id": "pattern-4-log-and-continue"
    },
    {
      "id": "decision-tree-how-to-handle-errors-ex0",
      "language": "mermaid",
      "code": "graph LR\n    Start{Error occurred?}\n\n    Start -->|Connection error| C1{Operation type?}\n    C1 -->|Read| C2[\"Graceful degradation<br/>fallback\"]\n    C1 -->|Write| C3[\"Log and continue<br/>or retry\"]\n    C1 -->|Critical| C4[\"Retry with backoff\"]\n\n    Start -->|Command error| Cmd1{Error source?}\n    Cmd1 -->|User input| Cmd2[\"Log and return<br/>error to user\"]\n    Cmd1 -->|Your code| Cmd3[\"Fail fast<br/>fix the bug\"]\n\n    Start -->|Data error| D1{Operation type?}\n    D1 -->|Read| D2[\"Log, invalidate,<br/>fallback\"]\n    D1 -->|Write| D3[\"Log and fail<br/>data is invalid\"]\n\n    Start -->|Resource error| R1{Error type?}\n    R1 -->|Redis loading| R2[\"Retry with backoff\"]\n    R1 -->|Pool exhausted| R3[\"Increase pool size\"]\n    R1 -->|Memory full| R4[\"Check configuration\"]",
      "section_id": "decision-tree-how-to-handle-errors"
    },
    {
      "id": "what-to-log-ex0",
      "language": "python",
      "code": "logger.error(\n    \"Redis operation failed\",\n    extra={\n        \"error_type\": type(e).__name__,\n        \"operation\": \"get\",\n        \"key\": key,\n        \"attempt\": attempt,\n        \"timestamp\": datetime.now().isoformat(),\n    }\n)",
      "section_id": "what-to-log"
    },
    {
      "id": "catching-all-exceptions-ex0",
      "language": "python",
      "code": "try:\n    result = r.get(key)\nexcept Exception:  # Too broad - some errors indicate code problems.\n    pass",
      "section_id": "catching-all-exceptions"
    },
    {
      "id": "catching-all-exceptions-ex1",
      "language": "python",
      "code": "try:\n    result = r.get(key)\nexcept redis.ConnectionError:\n    # Handle connection error\n    pass",
      "section_id": "catching-all-exceptions"
    },
    {
      "id": "not-distinguishing-error-types-ex0",
      "language": "python",
      "code": "try:\n    result = r.get(key)\nexcept redis.ResponseError:\n    # Retry? This won't help if it's a syntax error.\n    retry()",
      "section_id": "not-distinguishing-error-types"
    },
    {
      "id": "not-distinguishing-error-types-ex1",
      "language": "python",
      "code": "try:\n    result = r.get(key)\nexcept redis.TimeoutError:\n    retry()  # Retry on timeout\nexcept redis.ResponseError:\n    raise   # Fail on syntax error",
      "section_id": "not-distinguishing-error-types"
    },
    {
      "id": "ignoring-connection-pool-errors-ex0",
      "language": "python",
      "code": "# Pool is exhausted, but we don't handle it\nresult = r.get(key)  # Might timeout waiting for connection",
      "section_id": "ignoring-connection-pool-errors"
    }
  ]
}
