0
# Retry Policies & Error Handling
1
2
The AWS Java SDK Core provides comprehensive retry logic with configurable policies, backoff strategies, and adaptive retry mechanisms to handle transient failures and service throttling.
3
4
## Core Retry Framework
5
6
### Retry Policy Configuration
7
8
```java { .api }
9
// Retry policy configuration
10
class RetryPolicy {
11
public RetryPolicy(RetryCondition retryCondition,
12
BackoffStrategy backoffStrategy,
13
int maxErrorRetry,
14
boolean honorMaxErrorRetryInClientConfig);
15
16
public RetryCondition getRetryCondition();
17
public BackoffStrategy getBackoffStrategy();
18
public int getMaxErrorRetry();
19
public boolean isMaxErrorRetryInClientConfigHonored();
20
public boolean shouldRetry(AmazonWebServiceRequest originalRequest,
21
AmazonClientException exception,
22
int retriesAttempted);
23
public long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest,
24
AmazonClientException exception,
25
int retriesAttempted);
26
27
// Retry condition interface
28
interface RetryCondition {
29
boolean shouldRetry(AmazonWebServiceRequest originalRequest,
30
AmazonClientException exception,
31
int retriesAttempted);
32
}
33
34
// Backoff strategy interface
35
interface BackoffStrategy {
36
long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest,
37
AmazonClientException exception,
38
int retriesAttempted);
39
}
40
}
41
42
// Predefined retry policies
43
class PredefinedRetryPolicies {
44
public static final RetryPolicy DEFAULT;
45
public static final RetryPolicy NO_RETRY_POLICY;
46
public static final RetryPolicy DEFAULT_MAX_ERROR_RETRY;
47
public static final int DEFAULT_MAX_ERROR_RETRY_COUNT = 3;
48
49
public static RetryPolicy getDynamoDBDefaultRetryPolicy();
50
public static RetryPolicy getDynamoDBDefaultRetryPolicyWithCustomMaxRetries(int maxRetries);
51
}
52
53
// Retry mode enumeration
54
enum RetryMode {
55
LEGACY("legacy"),
56
STANDARD("standard"),
57
ADAPTIVE("adaptive");
58
59
public String getName();
60
public static RetryMode fromName(String name);
61
}
62
63
// Retry utilities
64
class RetryUtils {
65
public static boolean isRetryableServiceException(AmazonServiceException exception);
66
public static boolean isThrottlingException(AmazonServiceException exception);
67
public static boolean isClockSkewException(AmazonServiceException exception);
68
public static boolean isRequestEntityTooLargeException(AmazonServiceException exception);
69
public static int getRetryDelayMillis(int retryAttempt, long baseDelayInMilliseconds);
70
}
71
72
// Retry policy adapter
73
class RetryPolicyAdapter {
74
public RetryPolicyAdapter(com.amazonaws.retry.v2.RetryPolicy v2RetryPolicy);
75
public boolean shouldRetry(AmazonWebServiceRequest originalRequest,
76
AmazonClientException exception,
77
int retriesAttempted);
78
public long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest,
79
AmazonClientException exception,
80
int retriesAttempted);
81
}
82
```
83
84
### Built-in Retry Conditions and Strategies
85
86
```java { .api }
87
// V2 compatible backoff strategy
88
class V2CompatibleBackoffStrategy implements RetryPolicy.BackoffStrategy {
89
public V2CompatibleBackoffStrategy(com.amazonaws.retry.v2.BackoffStrategy v2BackoffStrategy);
90
public long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest,
91
AmazonClientException exception,
92
int retriesAttempted);
93
}
94
95
// Predefined backoff strategies
96
class PredefinedBackoffStrategies {
97
public static final RetryPolicy.BackoffStrategy STANDARD;
98
public static final RetryPolicy.BackoffStrategy FULL_JITTER;
99
public static final RetryPolicy.BackoffStrategy EQUAL_JITTER;
100
public static final RetryPolicy.BackoffStrategy EXPONENTIAL;
101
102
public static RetryPolicy.BackoffStrategy createFixedDelayBackoffStrategy(long delayMillis);
103
public static RetryPolicy.BackoffStrategy createExponentialBackoffStrategy(long baseDelayMillis,
104
long maxDelayMillis);
105
}
106
```
107
108
## V2 Retry Framework
109
110
### V2 Retry Policy
111
112
```java { .api }
113
// V2 retry policy interface
114
interface RetryPolicy {
115
RetryCondition getRetryCondition();
116
BackoffStrategy getBackoffStrategy();
117
int getMaxErrorRetry();
118
119
// Builder for creating retry policies
120
static Builder builder() {
121
return new Builder();
122
}
123
124
class Builder {
125
public Builder retryCondition(RetryCondition retryCondition);
126
public Builder backoffStrategy(BackoffStrategy backoffStrategy);
127
public Builder maxErrorRetry(int maxErrorRetry);
128
public RetryPolicy build();
129
}
130
}
131
132
// V2 retry condition interface
133
interface RetryCondition {
134
boolean shouldRetry(RetryPolicyContext context);
135
}
136
137
// V2 backoff strategy interface
138
interface BackoffStrategy {
139
long computeDelayBeforeNextRetry(RetryPolicyContext context);
140
}
141
142
// Retry policy context
143
class RetryPolicyContext {
144
public static RetryPolicyContext builder();
145
public RetryPolicyContext originalRequest(AmazonWebServiceRequest originalRequest);
146
public RetryPolicyContext exception(AmazonClientException exception);
147
public RetryPolicyContext retriesAttempted(int retriesAttempted);
148
public RetryPolicyContext totalRequests(int totalRequests);
149
150
public AmazonWebServiceRequest originalRequest();
151
public AmazonClientException exception();
152
public int retriesAttempted();
153
public int totalRequests();
154
}
155
156
// Simple retry policy implementation
157
class SimpleRetryPolicy implements RetryPolicy {
158
public SimpleRetryPolicy(RetryCondition retryCondition,
159
BackoffStrategy backoffStrategy,
160
int maxErrorRetry);
161
162
public RetryCondition getRetryCondition();
163
public BackoffStrategy getBackoffStrategy();
164
public int getMaxErrorRetry();
165
}
166
```
167
168
### V2 Retry Conditions
169
170
```java { .api }
171
// OR combination of retry conditions
172
class OrRetryCondition implements RetryCondition {
173
public OrRetryCondition(RetryCondition... retryConditions);
174
public boolean shouldRetry(RetryPolicyContext context);
175
}
176
177
// AND combination of retry conditions
178
class AndRetryCondition implements RetryCondition {
179
public AndRetryCondition(RetryCondition... retryConditions);
180
public boolean shouldRetry(RetryPolicyContext context);
181
}
182
183
// Retry on specific exceptions
184
class RetryOnExceptionsCondition implements RetryCondition {
185
public RetryOnExceptionsCondition(Set<Class<? extends Exception>> exceptionsToRetryOn);
186
public boolean shouldRetry(RetryPolicyContext context);
187
}
188
189
// Retry on HTTP status codes
190
class RetryOnStatusCodeCondition implements RetryCondition {
191
public RetryOnStatusCodeCondition(Set<Integer> statusCodesToRetryOn);
192
public boolean shouldRetry(RetryPolicyContext context);
193
}
194
195
// Maximum retry attempts condition
196
class MaxNumberOfRetriesCondition implements RetryCondition {
197
public MaxNumberOfRetriesCondition(int maxNumberOfRetries);
198
public boolean shouldRetry(RetryPolicyContext context);
199
}
200
```
201
202
### V2 Backoff Strategies
203
204
```java { .api }
205
// Fixed delay backoff strategy
206
class FixedDelayBackoffStrategy implements BackoffStrategy {
207
public FixedDelayBackoffStrategy(long delayInMilliseconds);
208
public long computeDelayBeforeNextRetry(RetryPolicyContext context);
209
}
210
```
211
212
## Usage Examples
213
214
### Basic Retry Policy Configuration
215
216
```java
217
import com.amazonaws.retry.*;
218
import com.amazonaws.ClientConfiguration;
219
220
// Use default retry policy
221
ClientConfiguration config = new ClientConfiguration()
222
.withRetryPolicy(PredefinedRetryPolicies.DEFAULT);
223
224
// Use no retry policy
225
ClientConfiguration noRetryConfig = new ClientConfiguration()
226
.withRetryPolicy(PredefinedRetryPolicies.NO_RETRY_POLICY);
227
228
// Use default with custom max retries
229
ClientConfiguration customRetryConfig = new ClientConfiguration()
230
.withMaxErrorRetry(5)
231
.withRetryPolicy(PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY);
232
```
233
234
### Custom Retry Policy
235
236
```java
237
import com.amazonaws.retry.*;
238
import com.amazonaws.*;
239
240
// Custom retry condition
241
RetryPolicy.RetryCondition customCondition = new RetryPolicy.RetryCondition() {
242
@Override
243
public boolean shouldRetry(AmazonWebServiceRequest originalRequest,
244
AmazonClientException exception,
245
int retriesAttempted) {
246
// Retry on service exceptions with 5xx status codes
247
if (exception instanceof AmazonServiceException) {
248
AmazonServiceException ase = (AmazonServiceException) exception;
249
return ase.getStatusCode() >= 500 && retriesAttempted < 5;
250
}
251
252
// Retry on specific client exceptions
253
if (exception instanceof AmazonClientException) {
254
String message = exception.getMessage().toLowerCase();
255
return (message.contains("connection") || message.contains("timeout"))
256
&& retriesAttempted < 3;
257
}
258
259
return false;
260
}
261
};
262
263
// Custom backoff strategy with exponential backoff and jitter
264
RetryPolicy.BackoffStrategy customBackoff = new RetryPolicy.BackoffStrategy() {
265
@Override
266
public long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest,
267
AmazonClientException exception,
268
int retriesAttempted) {
269
// Base delay: 100ms * 2^retryAttempt
270
long baseDelay = 100 * (1L << retriesAttempted);
271
272
// Add jitter (random delay up to 50% of base delay)
273
long jitter = (long) (Math.random() * baseDelay * 0.5);
274
275
// Cap at 10 seconds
276
return Math.min(baseDelay + jitter, 10000);
277
}
278
};
279
280
// Create custom retry policy
281
RetryPolicy customRetryPolicy = new RetryPolicy(
282
customCondition,
283
customBackoff,
284
5, // max retry attempts
285
true // honor client config max retry
286
);
287
288
// Use custom retry policy
289
ClientConfiguration config = new ClientConfiguration()
290
.withRetryPolicy(customRetryPolicy);
291
```
292
293
### V2 Retry Framework Usage
294
295
```java
296
import com.amazonaws.retry.v2.*;
297
import java.util.*;
298
299
// Create retry conditions
300
RetryCondition serviceErrorCondition = new RetryOnStatusCodeCondition(
301
new HashSet<>(Arrays.asList(500, 502, 503, 504))
302
);
303
304
RetryCondition throttlingCondition = new RetryOnStatusCodeCondition(
305
new HashSet<>(Arrays.asList(429))
306
);
307
308
RetryCondition maxRetriesCondition = new MaxNumberOfRetriesCondition(3);
309
310
// Combine conditions
311
RetryCondition combinedCondition = new AndRetryCondition(
312
new OrRetryCondition(serviceErrorCondition, throttlingCondition),
313
maxRetriesCondition
314
);
315
316
// Create backoff strategy
317
BackoffStrategy backoffStrategy = new FixedDelayBackoffStrategy(1000); // 1 second
318
319
// Create V2 retry policy
320
com.amazonaws.retry.v2.RetryPolicy v2RetryPolicy =
321
com.amazonaws.retry.v2.RetryPolicy.builder()
322
.retryCondition(combinedCondition)
323
.backoffStrategy(backoffStrategy)
324
.maxErrorRetry(3)
325
.build();
326
327
// Adapt to V1 retry policy
328
RetryPolicy v1RetryPolicy = new RetryPolicyAdapter(v2RetryPolicy);
329
330
// Use in client configuration
331
ClientConfiguration config = new ClientConfiguration()
332
.withRetryPolicy(v1RetryPolicy);
333
```
334
335
### DynamoDB-Specific Retry Configuration
336
337
```java
338
import com.amazonaws.retry.*;
339
340
// Use DynamoDB default retry policy (handles throttling)
341
RetryPolicy dynamoRetryPolicy = PredefinedRetryPolicies.getDynamoDBDefaultRetryPolicy();
342
343
// DynamoDB with custom max retries
344
RetryPolicy dynamoCustomRetryPolicy =
345
PredefinedRetryPolicies.getDynamoDBDefaultRetryPolicyWithCustomMaxRetries(10);
346
347
ClientConfiguration dynamoConfig = new ClientConfiguration()
348
.withRetryPolicy(dynamoRetryPolicy);
349
```
350
351
### Retry Mode Configuration
352
353
```java
354
import com.amazonaws.retry.RetryMode;
355
import com.amazonaws.SDKGlobalConfiguration;
356
357
// Set global retry mode
358
System.setProperty(SDKGlobalConfiguration.RETRY_MODE_SYSTEM_PROPERTY,
359
RetryMode.ADAPTIVE.getName());
360
361
// Or set via environment variable: AWS_RETRY_MODE=adaptive
362
363
// Check current retry mode
364
String retryModeProperty = System.getProperty(SDKGlobalConfiguration.RETRY_MODE_SYSTEM_PROPERTY);
365
RetryMode currentMode = RetryMode.fromName(retryModeProperty);
366
```
367
368
### Advanced Retry Scenarios
369
370
```java
371
import com.amazonaws.retry.*;
372
import com.amazonaws.*;
373
374
// Retry policy for specific error codes
375
RetryPolicy.RetryCondition errorCodeCondition = new RetryPolicy.RetryCondition() {
376
@Override
377
public boolean shouldRetry(AmazonWebServiceRequest originalRequest,
378
AmazonClientException exception,
379
int retriesAttempted) {
380
if (exception instanceof AmazonServiceException) {
381
AmazonServiceException ase = (AmazonServiceException) exception;
382
String errorCode = ase.getErrorCode();
383
384
// Retry on specific error codes
385
Set<String> retryableErrorCodes = new HashSet<>(Arrays.asList(
386
"Throttling", "ThrottledException", "ServiceUnavailable",
387
"InternalError", "RequestTimeout"
388
));
389
390
return retryableErrorCodes.contains(errorCode) && retriesAttempted < 5;
391
}
392
return false;
393
}
394
};
395
396
// Backoff with different strategies for different error types
397
RetryPolicy.BackoffStrategy adaptiveBackoff = new RetryPolicy.BackoffStrategy() {
398
@Override
399
public long delayBeforeNextRetry(AmazonWebServiceRequest originalRequest,
400
AmazonClientException exception,
401
int retriesAttempted) {
402
if (exception instanceof AmazonServiceException) {
403
AmazonServiceException ase = (AmazonServiceException) exception;
404
405
// Longer delay for throttling
406
if (RetryUtils.isThrottlingException(ase)) {
407
return Math.min(1000 * (1L << retriesAttempted), 32000); // Cap at 32s
408
}
409
410
// Shorter delay for server errors
411
if (ase.getStatusCode() >= 500) {
412
return Math.min(200 * (1L << retriesAttempted), 5000); // Cap at 5s
413
}
414
}
415
416
// Default exponential backoff
417
return Math.min(100 * (1L << retriesAttempted), 10000); // Cap at 10s
418
}
419
};
420
421
// Create adaptive retry policy
422
RetryPolicy adaptiveRetryPolicy = new RetryPolicy(
423
errorCodeCondition,
424
adaptiveBackoff,
425
8, // Higher max retries for adaptive policy
426
true
427
);
428
```
429
430
### Retry Utilities Usage
431
432
```java
433
import com.amazonaws.retry.RetryUtils;
434
import com.amazonaws.AmazonServiceException;
435
436
// Check if exception is retryable
437
public boolean handleException(AmazonServiceException exception) {
438
if (RetryUtils.isRetryableServiceException(exception)) {
439
System.out.println("Exception is retryable: " + exception.getErrorCode());
440
441
if (RetryUtils.isThrottlingException(exception)) {
442
System.out.println("Request was throttled");
443
// Implement exponential backoff with jitter
444
} else if (RetryUtils.isClockSkewException(exception)) {
445
System.out.println("Clock skew detected");
446
// Adjust system time or use server time
447
} else if (RetryUtils.isRequestEntityTooLargeException(exception)) {
448
System.out.println("Request payload too large");
449
// Reduce request size or use multipart upload
450
}
451
452
return true;
453
}
454
455
return false;
456
}
457
458
// Calculate retry delay
459
public long calculateRetryDelay(int retryAttempt) {
460
long baseDelay = 1000; // 1 second base delay
461
return RetryUtils.getRetryDelayMillis(retryAttempt, baseDelay);
462
}
463
```
464
465
### Exception-Specific Retry Logic
466
467
```java
468
import com.amazonaws.retry.v2.*;
469
import java.util.*;
470
471
// Retry on connection exceptions
472
Set<Class<? extends Exception>> connectionExceptions = new HashSet<>();
473
connectionExceptions.add(java.net.ConnectException.class);
474
connectionExceptions.add(java.net.SocketTimeoutException.class);
475
connectionExceptions.add(java.net.UnknownHostException.class);
476
477
RetryCondition connectionRetryCondition =
478
new RetryOnExceptionsCondition(connectionExceptions);
479
480
// Retry on specific HTTP status codes
481
Set<Integer> retryableStatusCodes = new HashSet<>();
482
retryableStatusCodes.add(408); // Request Timeout
483
retryableStatusCodes.add(429); // Too Many Requests
484
retryableStatusCodes.add(500); // Internal Server Error
485
retryableStatusCodes.add(502); // Bad Gateway
486
retryableStatusCodes.add(503); // Service Unavailable
487
retryableStatusCodes.add(504); // Gateway Timeout
488
489
RetryCondition statusCodeRetryCondition =
490
new RetryOnStatusCodeCondition(retryableStatusCodes);
491
492
// Combine with max retries
493
RetryCondition finalCondition = new AndRetryCondition(
494
new OrRetryCondition(connectionRetryCondition, statusCodeRetryCondition),
495
new MaxNumberOfRetriesCondition(5)
496
);
497
```
498
499
## Retry Best Practices
500
501
1. **Use Appropriate Retry Policies**: Start with predefined policies and customize only when necessary.
502
503
2. **Implement Exponential Backoff**: Use exponential backoff with jitter to avoid thundering herd problems.
504
505
3. **Set Maximum Retry Limits**: Always set reasonable maximum retry limits to prevent infinite loops.
506
507
4. **Handle Different Error Types**: Implement different retry logic for throttling vs server errors vs network errors.
508
509
5. **Monitor Retry Metrics**: Track retry attempts and success rates to tune retry policies.
510
511
6. **Consider Circuit Breakers**: For high-volume applications, consider implementing circuit breaker patterns.
512
513
7. **Service-Specific Policies**: Use service-specific retry policies (e.g., DynamoDB) when available.
514
515
8. **Adaptive Retry**: Consider using adaptive retry mode for applications with varying traffic patterns.
516
517
9. **Timeout Configuration**: Ensure retry timeouts are configured appropriately with overall request timeouts.
518
519
10. **Error Logging**: Log retry attempts with appropriate detail for debugging and monitoring.
520
521
The retry system provides comprehensive error handling and resilience capabilities, enabling applications to gracefully handle transient failures and service throttling with configurable retry logic and backoff strategies.