quickwit-oss/quickwit · error
ingester service should be initialized
Error message
ingester service should be initialized
What it means
`build_ingester_service` reached the self-node branch but the optional ingester service instance was `None`, violating the internal invariant that a node listing itself as an ingester must have built and injected the local service. This expect is a programming/configuration wiring error, not a user-input error.
Solutions
- Ensure the `ingester` service is enabled for this node (enabled_services / indexer/ingester split)
- Ensure the ingester service was successfully built before serve_quickwit assembles the cluster changes
- Report as a bug if the ingester service is enabled and initialized yet the expect still fires
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at quickwit/quickwit-serve/src/lib.rs:1301 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/4d8a305b0b9f78ec.
Report an issue: GitHub.
Appendix: source
Thrown at quickwit/quickwit-serve/src/lib.rs:1301
generation_id = %chitchat_id.generation_id,
"removing node `{}` from ingester pool",
chitchat_id.node_id,
);
let node_id: NodeId = node.node_id.clone();
Change::Remove(node_id)
}
fn build_ingester_service(
node: &ClusterNode,
ingester_opt: Option<impl IngesterService>,
max_message_size: ByteSize,
grpc_compression_encoding_opt: Option<CompressionEncoding>,
) -> IngesterServiceClient {
if node.is_self_node() {
// Here, since the service is available locally, we bypass the network stack
// and use the instance directly. However, we still want client-side
// metrics, so we use both metrics layers.
let ingester = ingester_opt.expect("ingester service should be initialized");
let service = ingester_service_layer_stack(
IngesterServiceClient::tower().stack_layer(INGEST_GRPC_CLIENT_METRICS_LAYER.clone()),
)
.build(ingester);
return service;
}
IngesterServiceClient::tower()
.stack_layer(INGEST_GRPC_CLIENT_METRICS_LAYER.clone())
.stack_layer(TimeoutLayer::new(GRPC_INGESTER_SERVICE_TIMEOUT))
.build_from_channel(
node.grpc_advertise_addr,
node.channel(),
max_message_size,
grpc_compression_encoding_opt,
)
}
async fn setup_searcher(View on GitHub (pinned to a39730c5cd)