{"record":{"id":"e86507823ecb02f1","repo":"testcontainers/testcontainers-java","slug":"retrying-flaky-annotated-test","errorCode":null,"errorMessage":"Retrying @Flaky-annotated test: {}","messagePattern":"Retrying @Flaky-annotated test: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"test-support/src/main/java/org/testcontainers/testsupport/FlakyTestJUnit4RetryRule.java","lineNumber":92,"sourceCode":"        private final int maxTries;\n\n        RetryingStatement(Statement base, Description description, int maxTries) {\n            this.base = base;\n            this.description = description;\n            this.maxTries = maxTries;\n        }\n\n        @Override\n        public void evaluate() {\n            int attempts = 0;\n            final List<Throwable> causes = new ArrayList<>();\n\n            while (++attempts <= maxTries) {\n                try {\n                    base.evaluate();\n                    return;\n                } catch (Throwable throwable) {\n                    log.warn(\"Retrying @Flaky-annotated test: {}\", description.getDisplayName());\n                    causes.add(throwable);\n                }\n            }\n\n            throw new IllegalStateException(\n                \"@Flaky-annotated test failed despite retries.\",\n                new MultipleFailureException(causes)\n            );\n        }\n    }\n}\n","sourceCodeStart":74,"sourceCodeEnd":104,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/test-support/src/main/java/org/testcontainers/testsupport/FlakyTestJUnit4RetryRule.java#L74-L104","documentation":"FlakyTestJUnit4RetryRule.evaluate logs this warning each time a test annotated @Flaky fails and is retried, up to maxTries attempts. The rule swallows each failure into a causes list and re-runs base.evaluate(); only when all retries are exhausted does it throw IllegalStateException. Seeing this message repeatedly means a test is genuinely failing and being papered over.","triggerScenarios":"A @Flaky-annotated JUnit4 test throwing any Throwable during base.evaluate() while FlakyTestJUnit4RetryRule is applied; the rule retries and logs this warning per failed attempt.","commonSituations":"Flaky integration tests hitting timing/race issues (e.g. waiting on containers); network hiccups against testcontainers-hosted services; asserting on eventually-consistent state.","solutions":["Fix the underlying flakiness: use Awaitility/polling instead of fixed sleeps and assert after the container is ready.","Inspect the final IllegalStateException's collected causes for the root failure of the last attempt.","Remove @Flaky so the failure is surfaced immediately rather than retried and hidden."],"exampleFix":"// before\n@Test @Flaky\npublic void pollsService() { assertServiceUp(); } // fails intermittently\n// after\n@Test\npublic void pollsService() {\n    await().atMost(Duration.ofSeconds(30)).untilAsserted(this::assertServiceUp);\n}","handlingStrategy":"retry","validationCode":"// pre-flight: ensure container is ready before the test runs\ncontainer.isRunning();","typeGuard":null,"tryCatchPattern":"try {\n    rule.apply(base, description).evaluate();\n} catch (IllegalStateException e) {\n    // all retries exhausted; inspect e for aggregated causes\n    log.error(\"Flaky test failed after retries\", e);\n    throw e;\n}","preventionTips":["Replace fixed sleeps with Awaitility/polling assertions","Investigate the aggregated causes instead of relying on retries","Remove @Flaky once the test is stabilized so failures surface immediately"],"tags":["junit","flaky-test","retry"],"backgroundTag":"retry-exhausted","analyzedSha":"8e549514e3f01c57d70546fbb8599d138f3903e5","analyzedAt":"2026-09-12T14:56:41.227Z","contentChangedAt":"2026-09-12T14:56:41.227Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}