spring-projects/spring-ai · error · IllegalArgumentException

Unsupported Qdrant value type:

Error message

Unsupported Qdrant value type: 

What it means

QdrantValueFactory.value(Object) maps a Java value into a Qdrant protobuf Value and only supports String, Integer/Long (as string), Double, Float, and Boolean plus lists. Any other type hits the default branch and throws IllegalArgumentException 'Unsupported Qdrant value type: <class>'. This guards the mapping layer from values Qdrant's protocol cannot represent.

Solutions

  1. Convert unsupported types to supported ones before adding metadata: LocalDate.toString(), enum.name(), uuid.toString()
  2. Replace BigDecimal/BigInteger with Double or its String form
  3. Flatten nested Maps into string (JSON) or list-of-scalars form
  4. Normalize metadata centrally in one helper before constructing Documents

Example fix

// before
metadata.put("created", LocalDate.now());
// after
metadata.put("created", LocalDate.now().toString());
Defensive patterns

Strategy: type-guard

Validate before calling

Set<Class<?>> ok = Set.of(String.class, Integer.class, Long.class, Double.class, Float.class, Boolean.class); metadata.values().forEach(v -> { if (!ok.contains(v.getClass()) && !(v instanceof List)) throw new IllegalArgumentException("Unsupported metadata type: " + v.getClass()); });

Type guard

static boolean isQdrantValue(Object v) { return v instanceof String || v instanceof Integer || v instanceof Long || v instanceof Double || v instanceof Float || v instanceof Boolean || v instanceof List; }

Try / catch

try { vectorStore.add(docs); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Unsupported Qdrant value type")) { /* normalize metadata */ } else throw e; }

Prevention

When it happens

Trigger: Storing document metadata whose value is a type like LocalDate, BigDecimal, byte[], Map, or a custom POJO when adding documents to QdrantVectorStore.

Common situations: Passing raw domain objects (dates, enums, UUIDs, BigDecimal) into Document metadata; upgrading code where metadata previously held only primitives; JSON-deserialized metadata containing nested objects.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at vector-stores/spring-ai-qdrant-store/src/main/java/org/springframework/ai/vectorstore/qdrant/QdrantValueFactory.java:83

		if (value instanceof Map) {
			return value((Map<String, @Nullable Object>) value);
		}

		if (value instanceof List) {
			return value((List<Object>) value);
		}

		return switch (value.getClass().getSimpleName()) {
			case "String" -> ValueFactory.value((String) value);
			case "Integer" -> ValueFactory.value((Integer) value);
			case "Long" ->
				// use String representation
				ValueFactory.value(String.valueOf(value));
			case "Double" -> ValueFactory.value((Double) value);
			case "Float" -> ValueFactory.value((Float) value);
			case "Boolean" -> ValueFactory.value((Boolean) value);
			default -> throw new IllegalArgumentException("Unsupported Qdrant value type: " + value.getClass());
		};
	}

	private static Value value(List<Object> elements) {
		List<Value> values = new ArrayList<>(elements.size());

		for (Object element : elements) {
			values.add(value(element));
		}

		return ValueFactory.list(values);
	}

	private static Value value(Object[] elements) {
		List<Value> values = new ArrayList<>(elements.length);

		for (Object element : elements) {
			values.add(value(element));

View on GitHub (pinned to 98a7beda4f)