{
  "schema_version": 2,
  "id": "develop/ai/redisvl/api/exceptions",
  "title": "Exceptions",
  "url": "https://redis.io/docs/latest/develop/ai/redisvl/api/exceptions/",
  "summary": "",
  "aliases": [
    "/integrate/redisvl/api/exceptions"
  ],
  "tags": [],
  "last_updated": "2026-08-10T10:42:48+02:00",
  "page_type": "content",
  "content_hash": "65b04a4c7e7421871a889fb84319f6a6817c6a4d9251859c98e2b638ed0ac4c7",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "RedisVL defines its custom exceptions in `redisvl.exceptions`. Every one of them\ninherits from [RedisVLError](#redisvlerror), so catching that single base class is enough to\nhandle any error the core index and query APIs raise on their own behalf. Catch the\nmore specific subclasses when you want to react differently to, for example, a\nschema validation failure than to a Redis connection problem. (The MCP integration\ndefines its own `redisvl.mcp.errors.RedisVLMCPError`, which is outside this\nhierarchy.)\n\n[code example]\n\n\nExceptions raised by the underlying `redis-py` client, such as\n`redis.exceptions.ConnectionError`, are not part of this hierarchy. Where\nRedisVL performs an index or search operation on your behalf it wraps those\nerrors in a [RedisSearchError](#redissearcherror) and chains the original exception, so the\nunderlying cause is still available on `__cause__`. Constructor and argument\nvalidation raises standard Python exceptions instead: for example,\n`VectorQuery(..., ef_runtime=-1)` raises `ValueError` at construction time,\nbefore any `try` block around the query run is entered."
    },
    {
      "id": "when-each-error-is-raised",
      "title": "When each error is raised",
      "role": "content",
      "text": "| Exception                                                                | Raised when                                                                                                                           | Typical entry points                                          |\n|--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|\n| [SchemaValidationError](#schemavalidationerror)     | An object does not match the index schema. Only raised when the index was<br/>created with `validate_on_load=True`.                   | `load()`                                                      |\n| [QueryValidationError](#queryvalidationerror)       | A query is not valid for the index it targets, for example setting<br/>`ef_runtime` on a vector field that uses the `flat` algorithm. | `query()`                                                     |\n| [RedisSearchError](#redissearcherror)               | An index or search operation fails, including errors returned by Redis<br/>itself.                                                    | `create()`, `exists()`, `delete()`, `search()`, `aggregate()` |\n| [RedisModuleVersionError](#redismoduleversionerror) | The connected Redis or Redis Search version does not support a requested<br/>feature, such as an `svs-vamana` vector field.           | `create()`                                                    |\n| [RedisVLError](#redisvlerror)                       | A load operation fails for a reason not covered by a more specific error.<br/>Also the base class for everything above.               | `load()`                                                      |\n\nAll of the above apply equally to [`SearchIndex`](https://redis.io/docs/latest/searchindex/#searchindex) and\n[`AsyncSearchIndex`](https://redis.io/docs/latest/searchindex/#asyncsearchindex)."
    },
    {
      "id": "handling-errors",
      "title": "Handling errors",
      "role": "content",
      "text": ""
    },
    {
      "id": "validating-data-on-load",
      "title": "`Validating data on load`",
      "role": "content",
      "text": "Schema validation is off by default. Pass `validate_on_load=True` to have RedisVL\ncheck each object against the index schema before writing it, and raise\n[SchemaValidationError](#schemavalidationerror) on the first object that does not match.\n\n[code example]\n\nThe error message reports the index of the object within the batch you passed, so a\nfailure part way through a large load still points at a specific record."
    },
    {
      "id": "handling-query-failures",
      "title": "`Handling query failures`",
      "role": "content",
      "text": "[QueryValidationError](#queryvalidationerror) signals a query that cannot run against this index. It\nis a programming error rather than a transient one, so it is usually worth failing\nloudly instead of retrying.\n\n[code example]"
    },
    {
      "id": "separating-configuration-problems-from-redis-problems",
      "title": "`Separating configuration problems from Redis problems`",
      "role": "content",
      "text": "[RedisModuleVersionError](#redismoduleversionerror) is a subclass of [RedisVLError](#redisvlerror), not of\n[RedisSearchError](#redissearcherror), so ordering the `except` clauses lets you distinguish an\nunsupported feature from a genuine Redis failure.\n\n[code example]\n\nInsufficient permissions usually arrive as [RedisSearchError](#redissearcherror) as well.\n`create()` checks whether the index already exists before doing anything, so a\ncredential that cannot run `FT.INFO` fails at that check rather than at\n`FT.CREATE`, with the chained `redis.exceptions.NoPermissionError` on\n`e.__cause__` naming the denied command. The same applies to an existing index whose\nkey prefix falls outside the credential’s key patterns; for an index that does not exist\nyet, the check simply reports it as absent and `create()` proceeds.\n\n`listall()` is the exception: it issues `FT._LIST` directly, so a permission failure\nthere raises `redis.exceptions.NoPermissionError` itself rather than a wrapped\n[RedisSearchError](#redissearcherror). See [Install RedisVL](https://redis.io/docs/latest/../user_guide/installation) for the ACL categories\nRedisVL needs."
    },
    {
      "id": "telling-the-index-is-missing-apart-from-other-failures",
      "title": "`Telling \"the index is missing\" apart from other failures`",
      "role": "content",
      "text": "Redis Search reports an absent index as an ordinary error reply rather than a distinct\ntype, and the wording has changed between versions – older releases say `Unknown index\nname`, Redis 8.6 and earlier say `<name>: no such index`, and Redis 8.8 introduced\n`SEARCH_INDEX_NOT_FOUND Index not found: <name>`. There is no error code to branch on,\nso code that needs to distinguish \"missing\" from \"something went wrong\" has to match the\nmessage.\n\n[`exists()`](https://redis.io/docs/latest/searchindex/#exists) already does this for you, which is the reason\nto prefer it over catching errors from [`info()`](https://redis.io/docs/latest/searchindex/#info): it\nreturns `False` only for a recognized missing-index reply and re-raises everything\nelse, so a permission or connection failure is never reported as an absent index.\n\n[code example]\n\nWhen you do need the distinction elsewhere, read `e.__cause__` rather than the\n[RedisSearchError](#redissearcherror) message: the wrapper interpolates the index name, so an index\nwhose name happens to contain one of the wordings above would make an unrelated failure\nlook like an absence."
    },
    {
      "id": "catching-everything",
      "title": "`Catching everything`",
      "role": "content",
      "text": "When the calling code only needs to know that the operation failed, catch the base\nclass.\n\n[code example]\n\nBecause RedisVL chains the underlying exception when it wraps one, `e.__cause__`\nstill holds the original `redis-py` error where there was one."
    },
    {
      "id": "exception-classes",
      "title": "Exception classes",
      "role": "errors",
      "text": ""
    },
    {
      "id": "redisvlerror",
      "title": "`RedisVLError`",
      "role": "content",
      "text": ""
    },
    {
      "id": "class-redisvlerror",
      "title": "`class RedisVLError`",
      "role": "content",
      "text": "Bases: `Exception`\n\nBase exception for all RedisVL errors."
    },
    {
      "id": "redissearcherror",
      "title": "`RedisSearchError`",
      "role": "content",
      "text": ""
    },
    {
      "id": "class-redissearcherror",
      "title": "`class RedisSearchError`",
      "role": "content",
      "text": "Bases: [RedisVLError](#redisvlerror)\n\nError raised for Redis Search specific operations."
    },
    {
      "id": "schemavalidationerror",
      "title": "`SchemaValidationError`",
      "role": "content",
      "text": ""
    },
    {
      "id": "class-schemavalidationerrormessage-indexnone",
      "title": "`class SchemaValidationError(message, index=None)`",
      "role": "content",
      "text": "Bases: [RedisVLError](#redisvlerror)\n\nError when validating data against a schema."
    },
    {
      "id": "queryvalidationerror",
      "title": "`QueryValidationError`",
      "role": "content",
      "text": ""
    },
    {
      "id": "class-queryvalidationerror",
      "title": "`class QueryValidationError`",
      "role": "content",
      "text": "Bases: [RedisVLError](#redisvlerror)\n\nError when validating a query."
    },
    {
      "id": "redismoduleversionerror",
      "title": "`RedisModuleVersionError`",
      "role": "content",
      "text": ""
    },
    {
      "id": "class-redismoduleversionerror",
      "title": "`class RedisModuleVersionError`",
      "role": "content",
      "text": "Bases: [RedisVLError](#redisvlerror)\n\nError when Redis or module versions are incompatible with requested features.\n\n#### `classmethod for_svs_vamana(min_redis_version)`\n\nCreate error for unsupported SVS-VAMANA.\n\n* **Parameters:**\n  **min_redis_version** (*str*) – Minimum required Redis version\n* **Returns:**\n  RedisModuleVersionError with formatted message"
    }
  ],
  "examples": [
    {
      "id": "overview-ex0",
      "language": "text",
      "code": "Exception\n└── RedisVLError\n    ├── RedisSearchError\n    ├── SchemaValidationError\n    ├── QueryValidationError\n    └── RedisModuleVersionError",
      "section_id": "overview"
    },
    {
      "id": "validating-data-on-load-ex0",
      "language": "python",
      "code": "from redisvl.index import SearchIndex\nfrom redisvl.exceptions import SchemaValidationError\n\nindex = SearchIndex.from_yaml(\n    \"schema.yaml\",\n    redis_url=\"redis://localhost:6379\",\n    validate_on_load=True,\n)\n\ntry:\n    index.load(data)\nexcept SchemaValidationError as e:\n    # The message identifies the offending object by its position in the\n    # input and describes which field failed and why.\n    print(f\"Invalid record: {e}\")",
      "section_id": "validating-data-on-load"
    },
    {
      "id": "handling-query-failures-ex0",
      "language": "python",
      "code": "from redisvl.query import VectorQuery\nfrom redisvl.exceptions import QueryValidationError\n\nquery = VectorQuery(\n    vector=[0.1, 0.2, 0.3],\n    vector_field_name=\"embedding\",\n    return_fields=[\"title\"],\n    ef_runtime=50,  # only supported by the 'hnsw' algorithm\n)\n\ntry:\n    results = index.query(query)\nexcept QueryValidationError as e:\n    print(f\"Query rejected: {e}\")",
      "section_id": "handling-query-failures"
    },
    {
      "id": "separating-configuration-problems-from-redis-problems-ex0",
      "language": "python",
      "code": "from redisvl.exceptions import RedisModuleVersionError, RedisSearchError\n\ntry:\n    index.create(overwrite=True)\nexcept RedisModuleVersionError as e:\n    # The deployment does not support the requested feature, for example an\n    # 'svs-vamana' field on a Redis version without a new enough Redis Search.\n    print(f\"Unsupported by this Redis deployment: {e}\")\nexcept RedisSearchError as e:\n    # Something went wrong talking to Redis, or the index definition was\n    # rejected. The original redis-py exception is available as e.__cause__.\n    print(f\"Index creation failed: {e}\")",
      "section_id": "separating-configuration-problems-from-redis-problems"
    },
    {
      "id": "telling-the-index-is-missing-apart-from-other-failures-ex0",
      "language": "python",
      "code": "# Prefer this\nif not index.exists():\n    index.create()\n\n# over inspecting the error yourself, which couples your code to the\n# wording of a particular Redis version\ntry:\n    index.info()\nexcept RedisSearchError as e:\n    if \"no such index\" in str(e):  # breaks on Redis 8.8\n        index.create()",
      "section_id": "telling-the-index-is-missing-apart-from-other-failures"
    },
    {
      "id": "catching-everything-ex0",
      "language": "python",
      "code": "from redisvl.exceptions import RedisVLError\n\ntry:\n    index.load(data)\n    results = index.query(query)\nexcept RedisVLError as e:\n    logger.error(\"RedisVL operation failed: %s\", e)\n    raise",
      "section_id": "catching-everything"
    }
  ]
}
