Resilience4j @Retry(maxAttempts=3) against a permanently-dead downstream: counting convention ============================================================================================= maxAttempts=3, downstream permanently down downstream calls before giving up: 3 Resilience4j's maxAttempts is the TOTAL call count (initial attempt included): 3, not 4. Core's @Retryable(maxRetries=3) is 3 retries AFTER the initial attempt: 4 total (see docs/output/03b-retryable-no-memory.txt). Same-sounding config, different arithmetic -- porting a maxRetries value from one to the other by name alone is off by one.