{"record":{"id":"24c6992d74224bd4","repo":"vectordotdev/vector","slug":"should-never-end","errorCode":null,"errorMessage":"Should never end","messagePattern":"Should never end","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/sinks/util/service/health.rs","lineNumber":182,"sourceCode":"                CircuitState::HalfOpen {\n                    permit: None,\n                    ref mut done,\n                } => {\n                    let done = Pin::new(done);\n                    ready!(done.poll(cx));\n\n                    if self.counters.healthy(self.snapshot).is_ok() {\n                        // A healthy response was observed\n                        info!(message = \"Endpoint is healthy.\", endpoint = %&self.endpoint);\n\n                        self.backoff.reset();\n                        self.open.clone().open(emit_active_endpoints);\n                        CircuitState::Closed\n                    } else {\n                        debug!(message = \"Endpoint failed probation.\", endpoint = %&self.endpoint);\n\n                        CircuitState::Open(\n                            sleep(self.backoff.next().expect(\"Should never end\")).boxed(),\n                        )\n                    }\n                }\n                CircuitState::Closed => {\n                    // Check for errors\n                    match self.counters.healthy(self.snapshot) {\n                        Ok(snapshot) => {\n                            // Healthy\n                            self.snapshot = snapshot;\n                            return self.inner.poll_ready(cx).map_err(Into::into);\n                        }\n                        Err(errors) if errors >= UNHEALTHY_AMOUNT_OF_ERRORS => {\n                            // Unhealthy\n                            warn!(message = \"Endpoint is unhealthy.\", endpoint = %&self.endpoint);\n                            CircuitState::Open(\n                                sleep(self.backoff.next().expect(\"Should never end\")).boxed(),\n                            )\n                        }","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/sinks/util/service/health.rs#L164-L200","documentation":"This panic fires in the health-check service's `poll_ready` when an endpoint fails probation and the circuit opens, but `backoff.next()` returns `None`. Vector's `ExponentialBackoff` is configured with `max_attempts: None` (unlimited), so the iterator never ends; the expect asserts that invariant.","triggerScenarios":"An endpoint fails its health probation period and the service transitions to `CircuitState::Open`; panic requires the backoff iterator to be exhausted, which the unlimited-attempts configuration prevents.","commonSituations":"Not reachable with default configuration; could only appear if the health service's backoff were constructed with a bounded attempt count.","solutions":["Report as a bug to Vector if observed.","Verify no custom build constrains the health backoff's max attempts."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not patch the health service to use a bounded backoff.","Report occurrences to Vector maintainers with logs of the probation transition.","Monitor endpoint health to reduce circuit-open transitions."],"tags":["rust","health-check","backoff","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}