Retry-After can suggest when to send another request after a 429 or 503 response. A header value is advice, not permission to exceed the caller's deadline or replay a non-idempotent operation.
Java Retry-After: parse a bounded server delay without inventing a retry
Operational contract
Retry-After permits delay seconds or an HTTP date. The deliberately narrow parser below accepts only non-negative decimal seconds of at most 47; longer delays are not shortened into an early retry. It returns empty for unsupported dates and malformed values, leaving the retry policy to decide a safe fallback. A header from an untrusted peer must not create an unbounded sleep. The caller also needs a maximum attempt count and a remaining time budget. If the original request changed state, it needs an idempotency key or reconciliation before retry.
Failure case
A catalog service answers 503 with Retry-After 82. This parser declines that delay rather than suggesting a retry after 47 seconds. The caller with only 12 seconds left stops. If a second response has a date-form header, the parser returns no delay instead of guessing from an invalid numeric conversion.
Java code
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Optional;
public class CatalogRetryHint {
public static Optional<Duration> delay(HttpResponse<?> response) {
int status = response.statusCode();
if (status != 429 && status != 503) return Optional.empty();
Optional<String> header = response.headers().firstValue("Retry-After");
if (header.isEmpty()) return Optional.empty();
String seconds = header.get().trim();
if (!seconds.matches("[0-9]{1,12}")) return Optional.empty();
try {
long delaySeconds = Long.parseLong(seconds);
return delaySeconds <= 47 ? Optional.of(Duration.ofSeconds(delaySeconds)) : Optional.empty();
} catch (NumberFormatException invalid) {
return Optional.empty();
}
}
}Performance and ownership cost
Parsing is O(H) in header length and uses O(H) temporary string storage. The regular-expression length cap prevents huge numeric inputs from being parsed. Sleeping consumes elapsed budget even when it consumes little CPU; the outer operation controls whether that cost is affordable.
Common Mistakes
- Do not sleep longer than the remaining operation budget.
- Do not treat unsupported date syntax as zero seconds.
- Do not retry a mutation solely because the server returned 503.
Connected lessons
- Java HTTP retry project: bounded attempts and one wait budget
- Java HttpClient deadlines: separate connection and request timeouts
- Java Optional: absence without hidden failure
- Java HTTP query values: encode data without changing URI structure
- Java HttpClient redirects: check the next origin before resending
- Java streaming HTTP bodies: close the stream and cap retained bytes
- Java HttpClient cookies: make session storage an owned policy
- Java HTTP and fork/join decisions quiz
- Advanced Java
