Spring Boot auto-configuration for AI retry capabilities with exponential backoff and intelligent HTTP error handling
Comprehensive guide to configuring Spring AI Retry Auto Configuration for different use cases and environments.
All properties use the prefix spring.ai.retry and can be set in:
application.propertiesapplication.ymlControls the total number of retry attempts (including the initial call).
spring.ai.retry.max-attempts=10Values:
100 to 100 (recommended)0 = no retries (fail immediately)1 = one attempt only10 = up to 10 total attemptsControls whether to retry 4xx client errors.
spring.ai.retry.on-client-errors=falseValues:
false (don't retry 4xx)true = retry 4xx errorsfalse = fail immediately on 4xxWhen to use true:
Highest precedence - these codes always trigger retry:
spring.ai.retry.on-http-codes=429,503Common values:
429 - Rate limit exceeded503 - Service unavailable502 - Bad gateway504 - Gateway timeoutThese codes never trigger retry:
spring.ai.retry.exclude-on-http-codes=401,403,400Common values:
401 - Unauthorized (invalid credentials)403 - Forbidden (insufficient permissions)400 - Bad request (invalid format)404 - Not foundTime to wait before first retry:
spring.ai.retry.backoff.initial-interval=2sFormats:
2000ms2s2mPT2SRecommended ranges:
100ms - 500ms500ms - 2s2s - 5s5s - 10sExponential growth factor for each retry:
spring.ai.retry.backoff.multiplier=5Values:
1 = fixed backoff (no growth)2 = moderate exponential growth3-5 = aggressive growth (default: 5)>5 = very aggressive growthBackoff progression examples:
With initial=2s:
Maximum wait time (cap on exponential growth):
spring.ai.retry.backoff.max-interval=3mFormats: Same as initial-interval
Recommended ranges:
500ms - 5s5s - 30s1m - 5mFast failure for rapid iteration:
# application-dev.properties
spring.ai.retry.max-attempts=2
spring.ai.retry.backoff.initial-interval=100ms
spring.ai.retry.backoff.multiplier=2
spring.ai.retry.backoff.max-interval=500msResult:
Quick retries for tests:
# application-test.properties
spring.ai.retry.max-attempts=3
spring.ai.retry.backoff.initial-interval=50ms
spring.ai.retry.backoff.multiplier=1
spring.ai.retry.backoff.max-interval=50msResult:
Robust retry for high reliability:
# application-prod.properties
spring.ai.retry.max-attempts=10
spring.ai.retry.on-http-codes=429,503
spring.ai.retry.exclude-on-http-codes=401,403,400
spring.ai.retry.backoff.initial-interval=2s
spring.ai.retry.backoff.multiplier=5
spring.ai.retry.backoff.max-interval=3mResult:
Respect rate limits with longer backoff:
spring.ai.retry.max-attempts=10
spring.ai.retry.on-http-codes=429,503
spring.ai.retry.backoff.initial-interval=5s
spring.ai.retry.backoff.multiplier=2
spring.ai.retry.backoff.max-interval=60sResult:
Quick retries for internal services:
spring.ai.retry.max-attempts=5
spring.ai.retry.backoff.initial-interval=500ms
spring.ai.retry.backoff.multiplier=3
spring.ai.retry.backoff.max-interval=10sResult:
Maximum resilience for critical operations:
spring.ai.retry.max-attempts=15
spring.ai.retry.backoff.initial-interval=3s
spring.ai.retry.backoff.multiplier=3
spring.ai.retry.backoff.max-interval=5mResult:
Complete YAML example:
spring:
ai:
retry:
# Core settings
max-attempts: 10
on-client-errors: false
# HTTP code lists
on-http-codes:
- 429 # Rate limit
- 503 # Service unavailable
- 502 # Bad gateway
- 504 # Gateway timeout
exclude-on-http-codes:
- 401 # Unauthorized
- 403 # Forbidden
- 400 # Bad request
- 404 # Not found
- 422 # Unprocessable entity
# Backoff settings
backoff:
initial-interval: 2s
multiplier: 5
max-interval: 3mHTTP error classification follows this precedence (highest to lowest):
Configuration:
spring.ai.retry.on-client-errors=false
spring.ai.retry.on-http-codes=429
spring.ai.retry.exclude-on-http-codes=400,503Results:
# application.yml
spring:
ai:
retry:
max-attempts: 10 # Default for all profiles
---
# application-dev.yml
spring:
config:
activate:
on-profile: dev
ai:
retry:
max-attempts: 2
backoff:
initial-interval: 100ms
---
# application-prod.yml
spring:
config:
activate:
on-profile: prod
ai:
retry:
max-attempts: 15
backoff:
initial-interval: 5s
max-interval: 5mimport org.springframework.ai.retry.autoconfigure.SpringAiRetryProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import java.time.Duration;
import java.util.Arrays;
@Configuration
public class RetryConfig {
@Bean
@Profile("dev")
public SpringAiRetryProperties devRetryProperties() {
SpringAiRetryProperties props = new SpringAiRetryProperties();
props.setMaxAttempts(2);
props.getBackoff().setInitialInterval(Duration.ofMillis(100));
return props;
}
@Bean
@Profile("prod")
public SpringAiRetryProperties prodRetryProperties() {
SpringAiRetryProperties props = new SpringAiRetryProperties();
props.setMaxAttempts(10);
props.setOnHttpCodes(Arrays.asList(429, 503));
props.getBackoff().setInitialInterval(Duration.ofSeconds(2));
return props;
}
}import org.springframework.retry.support.RetryTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CustomRetryConfig {
/**
* Custom RetryTemplate overrides auto-configured bean
*/
@Bean
public RetryTemplate retryTemplate() {
return RetryTemplate.builder()
.maxAttempts(5)
.fixedBackoff(1000)
.build();
}
}import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.ai.retry.TransientAiException;
import org.springframework.ai.retry.NonTransientAiException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
@Configuration
public class CustomErrorHandlerConfig {
@Bean
public ResponseErrorHandler responseErrorHandler() {
return new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return response.getStatusCode().isError();
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
int status = response.getStatusCode().value();
String message = "HTTP " + status;
if (status >= 500) {
throw new TransientAiException(message);
} else {
throw new NonTransientAiException(message);
}
}
};
}
}wait_time = min(initial_interval × multiplier^(retry_count - 1), max_interval)Default (initial=2s, multiplier=5, max=3m):
Attempt 1: 2s (2 × 5^0)
Attempt 2: 10s (2 × 5^1)
Attempt 3: 50s (2 × 5^2)
Attempt 4+: 180s (capped)
Total: ~22 minutesConservative (initial=500ms, multiplier=2, max=5s):
Attempt 1: 500ms
Attempt 2: 1s
Attempt 3: 2s
Attempt 4: 4s
Attempt 5+: 5s (capped)
Total: ~33s for 10 attemptsFixed (initial=2s, multiplier=1):
All attempts: 2s each
Total: 18s for 10 attemptsEnsure total retry time fits within timeout:
# If system timeout is 30s:
spring.ai.retry.max-attempts=5
spring.ai.retry.backoff.max-interval=5s
# Total: ~15-20s worst caseAlways specify important codes:
# Always retry rate limits
spring.ai.retry.on-http-codes=429,503
# Never retry auth errors
spring.ai.retry.exclude-on-http-codes=401,403External APIs:
spring.ai.retry.backoff.initial-interval=5s
spring.ai.retry.backoff.max-interval=60sInternal services:
spring.ai.retry.backoff.initial-interval=500ms
spring.ai.retry.backoff.max-interval=10sspring.ai.retry.backoff.multiplier=1
spring.ai.retry.backoff.initial-interval=2s
spring.ai.retry.backoff.max-interval=2sDevelopment:
spring.ai.retry.max-attempts=2
spring.ai.retry.backoff.max-interval=500msProduction:
spring.ai.retry.max-attempts=10
spring.ai.retry.backoff.max-interval=3mProblem: Application hangs with long retry delays
Solution: Reduce max-interval and max-attempts
spring.ai.retry.max-attempts=5
spring.ai.retry.backoff.max-interval=10sProblem: Wasting resources on non-transient errors
Solution: Add codes to exclude list
spring.ai.retry.exclude-on-http-codes=401,403,400,404,422Problem: Not recovering from rate limits
Solution: Add 429 to retry list
spring.ai.retry.on-http-codes=429
spring.ai.retry.backoff.initial-interval=5s
spring.ai.retry.backoff.max-interval=60sSee Configuration Properties Reference for complete details on all properties, types, and validation rules.
tessl i tessl/maven-org-springframework-ai--spring-ai-autoconfigure-retry@1.1.1