quickwit-oss/quickwit · error · ActorExitStatus
failed to get message from consumer: {:?}
Error message
failed to get message from consumer: {:?} What it means
Wraps an error returned by the Pulsar consumer while fetching the next message. The source actor converts the underlying consumer error into an ActorExitStatus after formatting it with debug formatting, so the root cause appears in the exit status. It means the receive operation itself failed, not that the stream was closed.
Source
Thrown at quickwit/quickwit-indexing/src/source/pulsar_source.rs:231
async fn emit_batches(
&mut self,
source_sink: &SourceSink,
ctx: &SourceContext,
) -> Result<Duration, ActorExitStatus> {
let now = Instant::now();
let mut batch_builder = BatchBuilder::new(SourceType::Pulsar);
let deadline = time::sleep(*EMIT_BATCHES_TIMEOUT);
tokio::pin!(deadline);
loop {
tokio::select! {
// This does not actually acquire the lock of the mutex internally
// we're using the mutex in order to convince the Rust compiler
// that we can use the consumer within this Sync context.
message = self.pulsar_consumer.next() => {
let message = message
.ok_or_else(|| ActorExitStatus::from(anyhow!("consumer was dropped")))?
.map_err(|e| ActorExitStatus::from(anyhow!("failed to get message from consumer: {:?}", e)))?;
self.process_message(message, &mut batch_builder).map_err(ActorExitStatus::from)?;
if batch_builder.num_bytes >= BATCH_NUM_BYTES_LIMIT {
break;
}
}
_ = &mut deadline => {
break;
}
}
ctx.record_progress();
}
if !batch_builder.checkpoint_delta.is_empty() {
debug!(
num_docs=%batch_builder.docs.len(),
num_bytes=%batch_builder.num_bytes,View on GitHub (pinned to a39730c5cd)
Solutions
- Inspect the wrapped error (`{:?}` payload in the message) for the underlying Pulsar error cause.
- Verify connectivity to the Pulsar broker (service URL, network, DNS) and that the topic/subscription still exist and permissions are valid.
- Check authentication credentials (token/JWT) haven't expired; refresh them.
- Restart the source actor; the Pulsar client typically reconnects on its own once the broker is reachable.
Example fix
// before
.map_err(|e| ActorExitStatus::from(anyhow!("failed to get message from consumer: {:?}", e)))?;
// after: log the underlying error for diagnostics
.map_err(|e| {
error!(error = ?e, "pulsar receive failed");
ActorExitStatus::from(anyhow!("failed to get message from consumer: {:?}", e))
})?; Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: verify broker reachability and topic access
pulsar_client.lookup_topic(&topic_url).await
.context("pulsar broker unreachable or topic missing before source start")?; Try / catch
match source_future.await {
Err(e) if e.to_string().contains("failed to get message from consumer") => {
warn!(error = %e, "pulsar receive failed; restarting source with backoff");
backoff(|| spawn_pulsar_source(cfg)).await?;
}
other => other?,
} Prevention
- Verify Pulsar service URL, credentials, and topic permissions before deployment.
- Monitor auth token expiry and rotate tokens before they lapse.
- Add retries with backoff around source restarts to survive broker restarts and network blips.
When it happens
Trigger: `pulsar_consumer.next()` yields `Some(Err(e))` — e.g. connection failure to the Pulsar broker, subscription lookup failure, deserialization error, or broker-side error while the actor is building its batch in `emit_batches`.
Common situations: Pulsar broker restart or network partition mid-consumption; authentication token expired; topic deleted or permissions revoked while running; consumer in a failed state after a protocol error.
Related errors
- consumer was dropped
- body stream ended with {} bytes pending; expected {target}
- body stream ended after skipping {copied} bytes; expected to
- no server currently available
- failed to parse host: `{host}`
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/a156cb68fda3132a.
Report an issue: GitHub.