spring-projects/spring-ai · error · RuntimeException

Could not create index: {0}

Error message

Could not create index: {0}

What it means

RedisVectorStore.afterPropertiesSet() creates the RediSearch index via jedisClient.ftCreate(...) with an FTCreateParams (JSON type + key prefix) and the computed schema. If the server's reply is not 'OK', it throws a RuntimeException 'Could not create index: {response}'. This typically means Redis rejected the FT.CREATE command.

Source

Thrown at vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/redis/RedisVectorStore.java:657

	}

	@Override
	public void afterPropertiesSet() {

		if (!this.initializeSchema) {
			return;
		}

		// If index already exists don't do anything
		if (this.jedisClient.ftList().contains(this.indexName)) {
			return;
		}

		String response = this.jedisClient.ftCreate(this.indexName,
				FTCreateParams.createParams().on(IndexDataType.JSON).addPrefix(this.prefix), schemaFields());
		if (!RESPONSE_OK.test(response)) {
			String message = MessageFormat.format("Could not create index: {0}", response);
			throw new RuntimeException(message);
		}
	}

	private Iterable<SchemaField> schemaFields() {
		Map<String, Object> vectorAttrs = new HashMap<>();
		vectorAttrs.put("DIM", this.embeddingModel.dimensions());
		vectorAttrs.put("DISTANCE_METRIC", this.distanceMetric.getRedisName());
		vectorAttrs.put("TYPE", VECTOR_TYPE_FLOAT32);

		// Add HNSW algorithm configuration parameters when using HNSW algorithm
		if (this.vectorAlgorithm == Algorithm.HNSW) {
			// M parameter: maximum number of connections per node in the graph (default:
			// 16)
			if (this.hnswM != null) {
				vectorAttrs.put("M", this.hnswM);
			}

			// EF_CONSTRUCTION parameter: size of dynamic candidate list during index

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Check the response text in the message: 'Index already exists' is usually benign on restart — pre-check with ftInfo or drop the stale index
  2. If DIM mismatch: drop the old index (FT.DROPINDEX) and let the store recreate it with the current embeddingModel.dimensions()
  3. Ensure Redis Stack (RediSearch + RedisJSON modules) is installed and the module version supports FT.CREATE with JSON
  4. Verify the Redis user has permissions to create indexes
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check before creating the store
try { jedisClient.ftInfo(indexName); /* exists -> drop or reuse */ } catch (JedisDataException e) { /* 'Unknown Index name' -> safe to create */ }
String modules = jedisClient.info("modules"); if (!modules.contains("search")) throw new IllegalStateException("RediSearch not loaded");

Try / catch

try { new RedisVectorStore(...).afterPropertiesSet(); } catch (RuntimeException e) { if (e.getMessage().contains("Could not create index") && e.getMessage().contains("already exists")) { /* reuse or FT.DROPINDEX then retry */ } }

Prevention

When it happens

Trigger: Initializing the RedisVectorStore bean (afterPropertiesSet) when the index already exists with different parameters, RediSearch module is missing/outdated, the schema is invalid (e.g. bad DIM), or the server replies with an error string.

Common situations: Application restart against a Redis where the index exists (older RediSearch versions error on duplicate index); Redis Stack not installed so ftCreate is unsupported; embedding dimensions changed while an old index with a different DIM exists; insufficient permissions.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/d98fecd0344a667d. Report an issue: GitHub.