{"record":{"id":"b8012407e2722e4e","repo":"spring-projects/spring-ai","slug":"retry-error-retry-count","errorCode":null,"errorMessage":"Retry error. Retry count:","messagePattern":"Retry error\\. Retry count:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java","lineNumber":82,"sourceCode":"\tpublic RetryTemplate retryTemplate(SpringAiRetryProperties properties) {\n\t\tRetryPolicy retryPolicy = RetryPolicy.builder()\n\t\t\t.maxRetries(properties.getMaxAttempts())\n\t\t\t.includes(TransientAiException.class)\n\t\t\t.includes(ResourceAccessException.class)\n\t\t\t.delay(properties.getBackoff().getInitialInterval())\n\t\t\t.multiplier(properties.getBackoff().getMultiplier())\n\t\t\t.maxDelay(properties.getBackoff().getMaxInterval())\n\t\t\t.build();\n\n\t\tRetryTemplate retryTemplate = new RetryTemplate(retryPolicy);\n\t\tretryTemplate.setRetryListener(new RetryListener() {\n\t\t\tprivate final AtomicInteger retryCount = new AtomicInteger(0);\n\n\t\t\t@Override\n\t\t\tpublic void onRetryFailure(RetryPolicy policy, Retryable<?> retryable, Throwable throwable) {\n\t\t\t\tint currentRetries = this.retryCount.incrementAndGet();\n\t\t\t\tif (logger.isWarnEnabled()) {\n\t\t\t\t\tlogger.warn(\"Retry error. Retry count:\" + currentRetries, throwable);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn retryTemplate;\n\t}\n\n\t@Bean\n\t@ConditionalOnMissingBean\n\tpublic ResponseErrorHandler responseErrorHandler(SpringAiRetryProperties properties) {\n\n\t\treturn new ResponseErrorHandler() {\n\n\t\t\t@Override\n\t\t\tpublic boolean hasError(ClientHttpResponse response) throws IOException {\n\t\t\t\treturn response.getStatusCode().isError();\n\t\t\t}\n\n\t\t\t@Override","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java#L64-L100","documentation":"SpringAiRetryAutoConfiguration registers a RetryListener whose onRetryFailure logs 'Retry error. Retry count:<n>' at WARN with the throwable. This is a log message, not a thrown error: it signals that a retryable operation (typically model API calls via RetryTemplate) failed and the backoff/retry policy is being applied.","triggerScenarios":"Any operation executed through the auto-configured RetryTemplate (e.g. OpenAI/other model client calls) that throws a retryable exception — transient 429/5xx responses, connection resets, timeouts — on each failed attempt including the final one.","commonSituations":"Rate limiting by the model provider; expired/invalid API key producing 401 (retried then exhausted); network flakiness in CI; overloaded upstream service.","solutions":["Inspect the attached throwable in the log to see the root cause (HTTP status or exception class).","For 429s, reduce request rate or configure larger backoff via spring.retry properties / RetryCustomizer.","For 401/403, fix the API key — retries will not help.","If retries exhaust, the final exception surfaces from the client call; handle it at the call site."],"exampleFix":"// application.properties: tune transient retry behavior\n// before (defaults)\n// after\nspring.retry.max-attempts=10\nspring.retry.backoff.initial-interval=2000\nspring.retry.backoff.multiplier=2","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { model.call(prompt); } catch (NonTransientAiException | RestClientException e) { /* after retries exhausted; check root cause logged by the RetryListener */ }","preventionTips":["Tune spring.retry max-attempts and backoff intervals for your provider's rate limits","Distinguish non-retryable errors (401/403) from transient ones (429/5xx) before retrying","Monitor WARN logs for retry-count trends as an early signal of upstream degradation"],"tags":["retry","resilience","spring","rate-limit"],"backgroundTag":"request-timeout","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}