spring-projects/spring-ai · error · IllegalArgumentException

Not allowed filter identifier name:

Error message

Not allowed filter identifier name: 

What it means

RedisFilterExpressionConverter.doKey validates that every filter field name is one of the configured metadata fields before emitting the @field: RediSearch query token. RediSearch query syntax has no escaping mechanism for field names, so unknown identifiers are rejected with IllegalArgumentException 'Not allowed filter identifier name: <name>' to prevent query injection through crafted field names.

Source

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

	@Override
	protected void doStartGroup(Group group, StringBuilder context) {
		context.append("(");
	}

	@Override
	protected void doEndGroup(Group group, StringBuilder context) {
		context.append(")");
	}

	@Override
	protected void doKey(Key key, StringBuilder context) {
		var identifier = key.key();
		// RediSearch field names are bare identifiers in the @field: query syntax
		// and have no escaping mechanism. Validate against the configured metadata
		// fields to prevent query injection through crafted field names.
		if (!this.metadataFields.containsKey(identifier)) {
			throw new IllegalArgumentException("Not allowed filter identifier name: " + identifier);
		}
		context.append("@").append(identifier).append(":");
	}

	@Override
	protected void doExpression(Expression expression, StringBuilder context) {
		switch (expression.type()) {
			case NIN:
				doExpression(negate(ExpressionType.IN, expression), context);
				break;
			case NE:
				doExpression(negate(ExpressionType.EQ, expression), context);
				break;
			case AND:
				doBinaryOperation(" ", expression, context);
				break;
			case OR:
				doBinaryOperation(" | ", expression, context);

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Register the field in RedisVectorStore.builder().metadataFields(MetadataField.tag("category"), ...)
  2. Correct the field-name typo in the filter expression to match a registered metadata field
  3. Keep a single shared constant list of metadata fields used by both document writing and filters
  4. Catch IllegalArgumentException from search if filters are user-supplied and sanitize them first

Example fix

// before
RedisVectorStore.builder(jedis, model).metadataFields(MetadataField.tag("type")).build();
// filter uses Filter.expr("category") -> error
// after
RedisVectorStore.builder(jedis, model).metadataFields(MetadataField.tag("type"), MetadataField.tag("category")).build();
Defensive patterns

Strategy: validation

Validate before calling

if (!registeredMetadataFields.containsKey(filterKey)) throw new IllegalArgumentException("Filter field not registered: " + filterKey);

Type guard

static boolean isAllowedField(String key, Map<String,MetadataField> fields) { return key != null && fields.containsKey(key); }

Try / catch

try { vectorStore.similaritySearch(request); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Not allowed filter identifier")) { /* reject/sanitize user filter */ } else throw e; }

Prevention

When it happens

Trigger: Using a FilterExpression whose key is not registered in RedisVectorStore's MetadataField configuration, e.g. Filter.expr("category") when only tags/price metadata fields were declared via metadataFields(...).

Common situations: Adding a new metadata key to documents but forgetting to register it in the store builder; typos in field names; switching stores without updating the allowed-field list.

Related errors


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