alibaba/spring-ai-alibaba · error · RuntimeException
Model call failed, maximum number of retries reached. ${maxA
Error message
Model call failed, maximum number of retries reached. ${maxAttempts} What it means
Defensive terminal throw after ModelRetryInterceptor's for-loop over attempts completes without returning — all maxAttempts attempts failed with retryable errors. It throws RuntimeException("Model call failed, maximum number of retries reached. " + maxAttempts) with the last exception as cause. (In practice usually unreachable because line 132-134 throws earlier on the final attempt.)
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/modelretry/ModelRetryInterceptor.java:160
// Wait and try again
if (currentDelay > 0) {
try {
log.info("Retry after {} ms", currentDelay);
Thread.sleep(currentDelay);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("Retry interrupted", ie);
}
}
// Calculate the next delay time (exponential backoff)
currentDelay = Math.min((long) (currentDelay * backoffMultiplier), maxDelay);
}
}
// All retries failed.
throw new RuntimeException("Model call failed, maximum number of retries reached. " + maxAttempts, lastException);
}
private Flux<ChatResponse> withStreamingRetry(ModelRequest request, ModelCallHandler handler, Flux<ChatResponse> responseFlux,
int attempt, long currentDelay) {
return Flux.defer(() -> {
AtomicBoolean chunkEmitted = new AtomicBoolean(false);
return responseFlux.doOnNext(response -> chunkEmitted.set(true)).onErrorResume(error -> {
if (chunkEmitted.get()) {
// Retrying after partial output would duplicate chunks downstream.
return Flux.error(error);
}
return retryStreamingModelCall(request, handler, attempt, currentDelay, error);
});
});
}
private Flux<ChatResponse> retryStreamingModelCall(ModelRequest request, ModelCallHandler handler, int failedAttempt,
long currentDelay, Throwable error) {View on GitHub (pinned to f82da0b50f)
Solutions
- Inspect the cause for the true final failure and check provider health/credentials.
- Increase maxAttempts, initialDelay, and maxDelay to ride out longer outages.
- Wrap with ModelFallbackInterceptor for cross-provider resilience.
- Add logging/metrics on retry exhaustion to alert before clients see this error.
Example fix
// before ModelRetryInterceptor.builder().maxAttempts(2).initialDelay(500).build(); // after ModelRetryInterceptor.builder().maxAttempts(5).initialDelay(1000).maxDelay(15000).backoffMultiplier(2.0).build();
Defensive patterns
Strategy: retry
Validate before calling
// Ensure sane retry budget before running ModelRetryInterceptor.Builder b = ModelRetryInterceptor.builder(); assert b != null; // configure maxAttempts>=3, maxDelay>=10s for production traffic
Try / catch
try {
return retryInterceptor.interceptModel(request, handler);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Model call failed, maximum number of retries reached. ")) {
log.error("Retry budget exhausted ({} attempts); final cause: {}", e.getMessage(), e.getCause());
return fallbackHandler.apply(request); // circuit-break / degrade
}
throw e;
} Prevention
- Use exponential backoff with a maxDelay high enough to ride out short outages.
- Add a circuit breaker so a down provider fails fast instead of burning the full retry budget on every request.
- Track retry-exhaustion rates in metrics/dashboards.
When it happens
Trigger: interceptModel where every attempt throws a retryable-predicate-passing exception and control flow exits the loop — logically equivalent to error 614 but reachable only if the final attempt's failure bypasses the earlier maxAttempts check.
Common situations: Sustained provider unavailability across the whole retry window; all attempts failing with retryable network errors (connection reset, timeout); retry budget too small relative to the outage duration.
Related errors
- Model call failed, maximum number of retries reached:${excep
- Model call failed, maximum number of retries reached.
- Failed to get valid decision after %d retries. Last invalid
- All models failed after ${fallbackModels.size() + 1} attempt
- INVALID_PARAMS
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/fea1463b40c0c462.
Report an issue: GitHub.