Documentation: CircuitBreakerConfig.Builder#maxWaitDurationInHalfOpenState javadoc still says HALF_OPEN waits for minimumNumberOfCalls (confirmed wrong in #1091 and #1869, never fixed)

Author: anonjjCreated Sep 17, 2026Updated Sep 17, 2026

Description

CircuitBreakerConfig.Builder#maxWaitDurationInHalfOpenState's javadoc still says:

By default CircuitBreaker will stay in Half Open state until minimumNumberOfCalls is completed with either success or failure.

https://github.com/resilience4j/resilience4j/blob/a8a33164256ddb6e4bbc168f5c47ac34a348ee7f/resilience4j-circuitbreaker/src/main/java/io/github/resilience4j/circuitbreaker/CircuitBreakerConfig.java#L544-L546

This is incorrect. HALF_OPEN's exit is governed by permittedNumberOfCallsInHalfOpenState, not minimumNumberOfCallsminimumNumberOfCalls only applies in the CLOSED state.

This has already been reported and confirmed twice, just never fixed in the source

  • #1091 (Oct 2020) flagged the identical wording error on the readme.io-hosted docs page. @RobWin acknowledged: "Thanks we have to refine the documentation." The issue was closed, but the in-source javadoc quoted above (present since the feature's introduction in #1042, mid-2020) was apparently never updated to match.
  • #1869 (Jan 2023) asked the same substantive question directly. @RobWin's answer was unambiguous:

    Only on permittedNumberOfCallsInHalfOpenState and, confirming minimumNumberOfCalls applies only in CLOSED state: Yes, correct

So this has been confirmed twice by a maintainer, but the javadoc in the actual source — which is what IDEs surface to users, as opposed to the external docs site — still contradicts both prior answers. What's new here isn't the finding, it's that it was never converted into an actual diff.

Scope — confirmed single-file, not duplicated elsewhere

Searched the whole repo for this wording (and for minimumNumberOfCalls co-occurring with Half/HalfOpen/half-open) across resilience4j-circuitbreaker, resilience4j-framework-common, resilience4j-commons-configuration, resilience4j-kotlin, resilience4j-vavr, and every .adoc file in the repo. The incorrect sentence exists exactly once, in the file linked above — the Spring/commons-configuration properties classes and the Kotlin/Vavr modules don't carry their own copy of this javadoc, and no .adoc source in this repo documents maxWaitDurationInHalfOpenState at all (the readme.io page #1091 was about must be sourced elsewhere). So this is a genuine one-line fix, not a multi-file sweep.

Independent confirmation

A live per-call CircuitBreaker event trace (CircuitBreaker.EventPublisher, logging getMetrics().getNumberOfBufferedCalls() on every event) against Resilience4j 2.2.0, on a TIME_BASED breaker with minimumNumberOfCalls=30 and permittedNumberOfCallsInHalfOpenState=3 (no maxWaitDurationInHalfOpenState set — the "by default" case this javadoc describes), shows HALF_OPEN evaluating and transitioning the instant exactly 3 calls complete — every call beyond the 3rd is rejected (NOT_PERMITTED) even mid-episode, well before 30 calls could ever be recorded. minimumNumberOfCalls never appears anywhere in the observed gating logic. This matches #1869's answer exactly, verified directly on the current 2.x line rather than taken on faith.

Suggested fix

Keeps the sentence's actual purpose (explaining what maxWaitDurationInHalfOpenState=0, the default, means — no time limit, exit once the probe calls complete) and only swaps which parameter counts those calls:

diff
- * By default CircuitBreaker will stay in Half Open state until
- * {@code minimumNumberOfCalls} is completed with either success or failure.
+ * By default CircuitBreaker will stay in Half Open state until
+ * {@code permittedNumberOfCallsInHalfOpenState} calls have completed with either
+ * success or failure.

Happy to open a PR with this if that's easier than a maintainer picking it up.

Source: resilience4j/resilience4j