quickwit-oss/quickwit · info
60 should be non-zero
Error message
60 should be non-zero
What it means
The serve startup creates an SMA rate estimator with 60 buckets for ingest rate tracking. The bucket count 60 is a hardcoded literal, and NonZeroUsize::new(60).expect documents the invariant that it is non-zero. This can only panic if the literal is refactored to a runtime value of 0.
Source
Thrown at quickwit/quickwit-serve/src/lib.rs:379
) -> anyhow::Result<IngestServiceClient> {
if disable_ingest_v1() {
debug!("returning no-op ingest service because ingest v1 is disabled");
let (balance_channel, _change_tx) = BalanceChannel::new();
let ingest_service = IngestServiceClient::from_balance_channel(
balance_channel,
node_config.grpc_config.max_message_size,
node_config.ingest_api_config.grpc_compression_encoding(),
);
return Ok(ingest_service);
}
if node_config.is_service_enabled(QuickwitService::Indexer) {
let ingest_api_service = start_ingest_api_service(
universe,
&node_config.data_dir_path,
&node_config.ingest_api_config,
)
.await?;
let num_buckets = NonZeroUsize::new(60).expect("60 should be non-zero");
let rate_estimator = SmaRateEstimator::new(
num_buckets,
Duration::from_secs(10),
Duration::from_millis(100),
);
let memory_capacity = ingest_api_service.ask(GetMemoryCapacity).await?;
let min_rate = ConstantRate::new(ByteSize::mib(1).as_u64(), Duration::from_millis(100));
let rate_modulator = RateModulator::new(rate_estimator.clone(), memory_capacity, min_rate);
let ingest_service = IngestServiceClient::tower()
.stack_ingest_layer(
ServiceBuilder::new()
.layer(EstimateRateLayer::<IngestRequest, _>::new(rate_estimator))
.layer(BufferLayer::new(100))
.layer(RateLimitLayer::new(rate_modulator))
.into_inner(),
)
.build_from_mailbox(ingest_api_service);
Ok(ingest_service)View on GitHub (pinned to a39730c5cd)
Solutions
- No action needed; it is a compile-time-safe assertion
- If making the bucket count configurable, validate it is > 0 in config parsing
Example fix
// before
let num_buckets = NonZeroUsize::new(60).expect("60 should be non-zero");
// after
let num_buckets = NonZeroUsize::new(node_config.ingest_api_config.rate_estimator_buckets)
.ok_or_else(|| anyhow::anyhow!("rate_estimator_buckets must be non-zero"))?; Defensive patterns
Strategy: validation
Validate before calling
// If bucket count becomes configurable, validate at config load:
if buckets == 0 { return Err(anyhow!("ingest rate estimator buckets must be > 0")); } Type guard
fn valid_buckets(n: usize) -> bool { n > 0 } Prevention
- Keep hardcoded non-zero literals for non-configurable values
- When making constants configurable, use NonZeroUsize in the config struct so 0 is unrepresentable
When it happens
Trigger: Only reachable if the hardcoded 60 is replaced by a configurable/derived value that evaluates to zero; as written it can never fire.
Common situations: Refactoring the ingest rate estimator to make bucket count configurable without guarding against 0.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- compactor service enabled but no compaction client available
- node not found in pending
- OTP logs or traces do not support VRL transforms
- `doc_batch` should not be empty
- Facet are not supported in quickwit yet.
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/70f136051b66613e.
Report an issue: GitHub.