spring-projects/spring-ai · error · RuntimeException

Got an unexpected error: %s

Error message

Got an unexpected error: %s

What it means

GemFireVectorStore.handleHttpClientException translates HTTP client exceptions into RuntimeExceptions. If the caught Throwable is not a WebClientResponseException (e.g. connect errors, timeouts, deserialization failures from WebClient), it throws RuntimeException("Got an unexpected error: %s"). It signals a non-HTTP-response failure during a GemFire REST call.

Source

Thrown at vector-stores/spring-ai-gemfire-store/src/main/java/org/springframework/ai/vectorstore/gemfire/GemFireVectorStore.java:337

		DeleteRequest deleteRequest = new DeleteRequest();
		this.client.method(HttpMethod.DELETE)
			.uri("/" + this.indexName)
			.body(BodyInserters.fromValue(deleteRequest))
			.retrieve()
			.bodyToMono(Void.class)
			.onErrorMap(WebClientException.class, this::handleHttpClientException)
			.block();
	}

	/**
	 * Handles exceptions that occur during HTTP client operations and maps them to
	 * appropriate runtime exceptions.
	 * @param ex the exception that occurred during HTTP client operation
	 * @return a mapped runtime exception corresponding to the HTTP client exception
	 */
	private Throwable handleHttpClientException(Throwable ex) {
		if (!(ex instanceof WebClientResponseException clientException)) {
			throw new RuntimeException(String.format("Got an unexpected error: %s", ex));
		}

		if (clientException.getStatusCode().equals(org.springframework.http.HttpStatus.NOT_FOUND)) {
			throw new RuntimeException(String.format("Index %s not found: %s", this.indexName, ex));
		}
		else if (clientException.getStatusCode().equals(org.springframework.http.HttpStatus.BAD_REQUEST)) {
			throw new RuntimeException(String.format("Bad Request: %s", ex));
		}
		else {
			throw new RuntimeException(String.format("Got an unexpected HTTP error: %s", ex));
		}
	}

	@Override
	public VectorStoreObservationContext.Builder createObservationContextBuilder(String operationName) {
		return VectorStoreObservationContext.builder(VectorStoreProvider.GEMFIRE.value(), operationName)
			.collectionName(this.indexName)
			.dimensions(this.embeddingModel.dimensions())

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Read the chained cause (ex) for the underlying connect/timeout error
  2. Verify the GemFire REST endpoint host/port and that the service is reachable (curl the endpoint)
  3. Check DNS, proxy, and TLS configuration between app and GemFire
  4. Increase WebClient connect/read timeouts if failures occur under load

Example fix

// before: wrong scheme/port
GemFireVectorStore.builder().host("localhost").port(8080)... 
// after: correct GemFire REST port and reachable host
GemFireVectorStore.builder().host("gemfire-host").port(7070)...
Defensive patterns

Strategy: try-catch

Validate before calling

boolean reachable = new Socket().connect(new InetSocketAddress(host, port), 3000); // wrap in try/catch

Try / catch

try {
    vectorStore.similaritySearch(request);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Got an unexpected error")) {
        logger.error("GemFire call failed without HTTP response: {}", e.getCause(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Any GemFire vector store operation (createIndex, similaritySearch, put/delete) whose WebClient call fails without producing an HTTP response: connection refused, DNS failure, read/write timeout, or response decoding error.

Common situations: GemFire REST endpoint URL misconfigured, GemFire server down or firewall blocking, TLS handshake failures, or reactive client timeout settings too low.

Related errors


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