quickwit-oss/quickwit · error

fatal_error (non-retryable batch error propagated via bail!)

Error message

fatal_error (non-retryable batch error propagated via bail!)

What it means

SQS queue source acknowledge() batches delete-message calls; if any returned batch error is non-retryable, it is fatal and propagated via bail! rather than being retried or logged away. Retryable batch errors are only rate-limited logged and left for a later attempt.

Source

Thrown at quickwit/quickwit-indexing/src/source/queue_sources/sqs_queue.rs:158

                    .set_entries(Some(batch.clone()))
                    .send()
            })
            .await;
            match res {
                Ok(res) => {
                    message_errors.extend(res.failed);
                }
                Err(err) => {
                    batch_errors.push(err);
                }
            }
        }
        if batch_errors.iter().any(|err| !err.is_retryable()) {
            let fatal_error = batch_errors
                .into_iter()
                .find(|err| !err.is_retryable())
                .unwrap();
            bail!(fatal_error);
        } else if !batch_errors.is_empty() {
            rate_limited_error!(
                limit_per_min = 10,
                count = batch_errors.len(),
                first_err = ?batch_errors.into_iter().next().unwrap(),
                "failed to acknowledge some message batches",
            );
        }
        // The documentation is unclear about these partial failures. We assume
        // it is either:
        // - a transient failure
        // - the message is already acknowledged
        // - the message is expired
        if !message_errors.is_empty() {
            rate_limited_error!(
                limit_per_min = 10,
                count = message_errors.len(),
                first_err = ?message_errors.into_iter().next().unwrap(),

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Ensure message deadlines are renewed (modify_deadlines) so receipt handles stay valid before acknowledgement.
  2. Check IAM permissions for sqs:DeleteMessage on the queue.
  3. Treat the fatal error upstream: the source will restart; verify whether the affected messages were already processed to avoid duplicates.
Defensive patterns

Strategy: retry

Try / catch

// Retryable errors are logged and retried; non-retryable ones abort the actor.
// Callers should let the pipeline restart and rely on at-least-once redelivery.
if let Err(fatal) = queue_source.acknowledge(&ack_ids).await {
    log::error!("fatal acknowledge error, source will restart: {fatal}");
}

Prevention

When it happens

Trigger: Calling acknowledge when the AWS SQS DeleteMessageBatch response contains at least one error whose is_retryable() is false (e.g., invalid message handle — message already deleted or visibility expired and deleted, or invalid permission).

Common situations: Messages whose visibility timeout expired and were re-delivered/deleted so the receipt handle is stale; IAM policy missing sqs:DeleteMessage; long processing without deadline renewal causing invalid handles.

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/b03b8119eb526c86. Report an issue: GitHub.