Spring Boot auto-configuration for AI retry capabilities with exponential backoff and intelligent HTTP error handling
Spring Boot auto-configuration for AI retry capabilities with exponential backoff and intelligent HTTP error handling.
Add the dependency to your Maven project:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-autoconfigure-retry</artifactId>
<version>1.1.2</version>
</dependency>Gradle:
implementation 'org.springframework.ai:spring-ai-autoconfigure-retry:1.1.2'The module auto-configures retry beans when on the classpath. No explicit configuration needed:
@Service
public class AiService {
private final RetryTemplate retryTemplate;
public AiService(RetryTemplate retryTemplate) {
this.retryTemplate = retryTemplate;
}
public String callAiModel() {
return retryTemplate.execute(context -> makeAiApiCall());
}
}Configure retry behavior in application.properties:
spring.ai.retry.max-attempts=10
spring.ai.retry.on-http-codes=429,503
spring.ai.retry.exclude-on-http-codes=401,403
spring.ai.retry.backoff.initial-interval=2s
spring.ai.retry.backoff.multiplier=5
spring.ai.retry.backoff.max-interval=3m| Bean | Type | Purpose |
|---|---|---|
retryTemplate | RetryTemplate | Handles retry logic with exponential backoff |
responseErrorHandler | ResponseErrorHandler | Classifies HTTP errors as transient/non-transient |
| Exception | Behavior | Use Case |
|---|---|---|
TransientAiException | Triggers retry | Server errors (5xx), rate limits, network errors |
NonTransientAiException | Fails immediately | Auth errors (401, 403), bad requests (400) |
Priority order for error handling:
| Property | Default | Description |
|---|---|---|
max-attempts | 10 | Total retry attempts |
on-client-errors | false | Retry 4xx errors |
backoff.initial-interval | 2s | First retry delay |
backoff.multiplier | 5 | Exponential growth factor |
backoff.max-interval | 3m | Maximum retry delay |
| Code | Default Behavior | Typical Use |
|---|---|---|
| 400 | No retry | Bad request (invalid format) |
| 401 | No retry | Authentication failure |
| 403 | No retry | Authorization failure |
| 429 | Retry | Rate limit exceeded |
| 500 | Retry | Internal server error |
| 503 | Retry | Service unavailable |
With default settings (initial: 2s, multiplier: 5, max: 3m):
| Attempt | Wait Time |
|---|---|
| 1 | 2s |
| 2 | 10s |
| 3 | 50s |
| 4+ | 180s (capped) |
// Execute with retry
<T> T execute(RetryCallback<T, ?> callback);
// Execute with recovery fallback
<T> T execute(RetryCallback<T, ?> callback, RecoveryCallback<T> recovery);// Configuration prefix: "spring.ai.retry"
int getMaxAttempts(); // Default: 10
boolean isOnClientErrors(); // Default: false
List<Integer> getOnHttpCodes(); // Default: []
List<Integer> getExcludeOnHttpCodes(); // Default: []
Backoff getBackoff(); // Nested configuration// Transient (retryable)
TransientAiException(String message);
TransientAiException(String message, Throwable cause);
// Non-transient (not retryable)
NonTransientAiException(String message);
NonTransientAiException(String message, Throwable cause);@ConditionalOnMissingBean┌─────────────────────────────────────┐
│ Spring Boot Auto-Configuration │
├─────────────────────────────────────┤
│ SpringAiRetryAutoConfiguration │
│ ├─ retryTemplate bean │
│ └─ responseErrorHandler bean │
└─────────────────────────────────────┘
↓ ↓
┌────────────────┐ ┌───────────────────┐
│ RetryTemplate │ │ ResponseErrorHandler│
│ - Max attempts│ │ - Error classification│
│ - Backoff │ │ - HTTP status codes │
│ - Listeners │ │ - Exception throwing │
└────────────────┘ └───────────────────┘
↓ ↓
┌─────────────────────────────────────┐
│ Exception Classification │
│ ├─ TransientAiException (retry) │
│ └─ NonTransientAiException (fail) │
└─────────────────────────────────────┘Required:
spring-ai-retry - Core retry utilitiesspring-boot-starter - Spring Boot coreOptional:
@Bean
public RestTemplate aiRestTemplate(ResponseErrorHandler errorHandler) {
RestTemplate template = new RestTemplate();
template.setErrorHandler(errorHandler);
return template;
}
@Service
public class AiService {
public String call(RetryTemplate retry, RestTemplate rest) {
return retry.execute(ctx -> rest.postForObject(url, request, String.class));
}
}@Service
public class ReactiveAiService {
public String call(RetryTemplate retry, WebClient client) {
return retry.execute(ctx ->
client.post().bodyValue(request).retrieve()
.bodyToMono(String.class).block()
);
}
}try {
return retryTemplate.execute(ctx -> callApi());
} catch (TransientAiException e) {
// All retries exhausted
return "Service temporarily unavailable";
} catch (NonTransientAiException e) {
// Permanent failure
return "Configuration error";
}Development (fast failure):
spring.ai.retry.max-attempts=2
spring.ai.retry.backoff.initial-interval=100ms
spring.ai.retry.backoff.max-interval=500msProduction (robust retry):
spring.ai.retry.max-attempts=10
spring.ai.retry.backoff.initial-interval=2s
spring.ai.retry.backoff.max-interval=3m
spring.ai.retry.on-http-codes=429,503
spring.ai.retry.exclude-on-http-codes=401,403tessl i tessl/maven-org-springframework-ai--spring-ai-autoconfigure-retry@1.1.1