alibaba/spring-ai-alibaba · error · RuntimeException
Model call failed, maximum number of retries reached.
Error message
Model call failed, maximum number of retries reached.
What it means
ModelRetryInterceptor's generic catch block: a direct exception from handler.call(request) occurred on the final allowed attempt (attempt >= maxAttempts), so it throws RuntimeException("Model call failed, maximum number of retries reached.") with the last exception preserved as the cause. The retry policy gave up after exhausting all attempts.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/modelretry/ModelRetryInterceptor.java:134
}
// For non-retryable exceptions, return immediately.
return modelResponse;
}
// Successful response
if (attempt > 1) {
log.info("The model call succeeded after the {}th attempt.", attempt);
}
return modelResponse;
} catch (Exception e) {
lastException = e;
log.warn("Model call failed (attempted {}/{}): {}", attempt, maxAttempts, e.getMessage());
if (attempt >= maxAttempts) {
log.error("The maximum number of retries has been reached {}, and the model call has failed.", maxAttempts);
throw new RuntimeException("Model call failed, maximum number of retries reached.", lastException);
}
// Determine if an exception can be retried.
if (!retryableExceptionPredicate.test(e)) {
log.warn("Exceptions cannot be retried and are thrown immediately: {}", e.getMessage());
throw new RuntimeException("Model call failed (non-retryable exception)", e);
}
// 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);
}
}View on GitHub (pinned to f82da0b50f)
Solutions
- Inspect getCause() of this RuntimeException — it holds the final underlying model-call exception; fix that root problem.
- Check provider status page and your API key validity/quota; 401/429 errors will fail every attempt.
- Raise maxAttempts or lengthen backoff if failures are transient bursts (rate limit spikes).
- Combine with ModelFallbackInterceptor so a different model is tried after retries are exhausted.
Example fix
// before: retries then hard failure ModelRetryInterceptor.builder().maxAttempts(3).build(); // after: retry then fall back to another provider var retry = ModelRetryInterceptor.builder().maxAttempts(3).build(); var fallback = ModelFallbackInterceptor.builder().addFallbackModel(otherProviderModel).build();
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate configuration before calling the model
if (apiKey == null || apiKey.isBlank()) throw new IllegalStateException("Missing provider API key");
if (modelName == null || !allowedModels.contains(modelName)) throw new IllegalStateException("Unknown model: " + modelName); 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.")) {
Throwable root = e.getCause();
log.error("All {} attempts failed; final cause: {}", maxAttempts, root, root);
throw new ModelCallException(root); // typed wrapper for callers
}
throw e;
} Prevention
- Verify API keys, model names, and quotas before deploying; 401/404 fail every attempt.
- Subscribe to provider status feeds and set up health probes.
- Combine retry with cross-provider fallback for resilience.
When it happens
Trigger: interceptModel where handler.call throws on every one of maxAttempts attempts (e.g. persistent HTTP 4xx/5xx, timeout, I/O error); on the final attempt the `attempt >= maxAttempts` check fires before the retryability predicate is consulted.
Common situations: Provider outage or sustained rate limiting outlasting the retry window; wrong API key causing every call to fail; model name not found on the target endpoint; local network/firewall blocking the provider consistently.
Related errors
- Model call failed, maximum number of retries reached:${excep
- Model call failed, maximum number of retries reached. ${maxA
- 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/388364d563684749.
Report an issue: GitHub.