Schedule icon
Webhook icon
Assert icon
ConsumerGroupDescribe icon
Script icon
Set icon
If icon
Loop icon
Produce icon
Pause icon
ConsumerGroupAlterOffsets icon
Log icon
SlackIncomingWebhook icon

Kafka Consumer Group Dead-Letter Rebalance and Offset Rewind Guard

Detect Kafka consumer group partition deadlocks and poison pills, safely rewind or skip offsets with dry-run verification, and audit recovery in Kestra.

Categories
DataInfrastructure

Production Apache Kafka streaming pipelines often experience consumer group deadlocks caused by poison pill records. When a consumer reads an unprocessable or malformed message, it throws an unhandled exception or exceeds its max.poll.interval.ms timeout. The consumer fails to commit the message offset, crashes, and leaves the partition uncommitted.

During the resulting rebalance, another consumer in the group receives the partition assignment, reads the exact same uncommitted poison offset, and crashes. This cycle creates a continuous rebalance storm where the committed offset never advances while the partition end offset continues to rise as upstream producers publish new records.

This blueprint provides an automated deadlock and rebalance guard that audits consumer group partition lag, detects frozen committed offsets against growing end offsets, isolates poison pill records to a dead-letter quarantine topic, safely skips or rewinds offsets with dry-run verification, and records recovery audit telemetry in Kestra KV and Slack.

How it works

  1. Pre-flight Assertion: The workflow asserts that input parameters meet sanity limits, ensuring valid consumer group names, non-negative lag thresholds, and positive rewind values.
  2. Consumer Group Metadata Collection: io.kestra.plugin.kafka.ConsumerGroupDescribe queries the Kafka AdminClient to retrieve group state (Stable, PreparingRebalance, CompletingRebalance, Empty), group coordinator, active members, assigned partitions, high-watermark end offsets, committed offsets, and lag.
  3. REST Proxy Diagnostic Cross-Check: If a Kafka REST Proxy URL is specified, the analysis script sends an HTTP query to verify broker cluster connectivity and consumer group status.
  4. Differential Lag and Deadlock Analysis: A Python inspection script compares current partition offsets against historical snapshots stored in the Kestra KV store under kafka_cg_tracker_{consumer_group_id}. A partition is classified as DEADLOCKED when its committed offset remains stationary while its end offset increases and accumulated lag crosses deadlock_lag_threshold.
  5. Poison Pill Offset Isolation: The script flags the stationary committed offset as the poison pill location, formats a structured dead-letter alert, and computes the target remediation offset based on the selected policy (SKIP_POISON_RECORD advances to offset + 1, REWIND_OFFSET rewinds by N messages).
  6. Dead-Letter Quarantine Publishing: If enabled, io.kestra.plugin.core.flow.Loop iterates over detected poison records and publishes diagnostic events to the quarantine topic using io.kestra.plugin.kafka.Produce.
  7. Safe Remediation with Approval Gate: When dry_run is disabled, the workflow pauses execution (io.kestra.plugin.core.flow.Pause) for operator review, executes io.kestra.plugin.kafka.ConsumerGroupAlterOffsets to update committed offsets, and re-describes the group to verify offset application.
  8. Telemetry and Incident Notification: The complete recovery audit manifest is stored in Kestra KV under kafka_deadlock_audit_{consumer_group_id}, and actionable Slack alerts are dispatched with diagnostic metrics and recovery status.

What you get

  • Automated detection of consumer group partition deadlocks and poison pill crashes.
  • Elimination of recursive rebalance storms without manual broker intervention.
  • Dead-letter quarantine publishing with topic, partition, bad offset, and error metadata.
  • Dual remediation strategies supporting single-record skipping (SKIP_POISON_RECORD) or multi-message rewind (REWIND_OFFSET).
  • Operator approval gates and dry-run verification to prevent accidental offset corruption.
  • Persistent KV store audit records under kafka_deadlock_audit_{consumer_group_id} for compliance tracking.

Who it's for

  • Streaming Platform Engineers operating Apache Kafka, Strimzi, or Confluent Cloud clusters.
  • Data Engineers maintaining real-time event ingestion and stream-processing microservices.
  • Site Reliability Engineers (SREs) triaging Kafka consumer group lag spikes and rebalance alerts.

Why orchestrate this with Kestra

Kafka brokers provide AdminClient and CLI commands like kafka-consumer-groups.sh, but they cannot track historical offset progression, store differential lag state, require human approval gates, or dispatch multi-channel alerts. Writing standalone daemon scripts creates unmonitored single points of failure that lack execution logs, credential encryption, and auditability.

Orchestrating this guard with Kestra delivers a declarative workflow with built-in state tracking in Kestra KV, native Kafka AdminClient integration, pause-and-resume approval mechanisms, secure secrets management, and automated Slack escalation.

Prerequisites

  • An accessible Apache Kafka cluster (version 2.4 or higher) reachable from the Kestra worker.
  • Target consumer group and topic partitions created on the Kafka cluster.
  • A Kafka dead-letter quarantine topic (e.g. orders-dead-letter-quarantine) for poison pill routing.
  • A Slack Incoming Webhook URL to receive incident alerts.

Secrets

  • SLACK_WEBHOOK_URL: Slack Incoming Webhook endpoint URL used for deadlock and failure alerts.
  • KAFKA_DEADLOCK_GUARD_WEBHOOK_KEY: Secret authentication token protecting the on-demand webhook trigger.

Quick start

  1. Configure SLACK_WEBHOOK_URL and KAFKA_DEADLOCK_GUARD_WEBHOOK_KEY in your Kestra namespace secrets.
  2. Import this blueprint and set bootstrap_servers and consumer_group_id to match your Kafka environment.
  3. Specify your dead-letter topic in quarantine_topic (e.g. orders-dead-letter-quarantine).
  4. Run a manual execution with dry_run: true to record an initial offset baseline and review detected partitions.
  5. Enable the periodic_deadlock_guard schedule trigger to monitor consumer group partitions continuously every 5 minutes.

How to extend

  • Automated Consumer Container Bounce: Add an io.kestra.plugin.kubernetes.pod.Delete task to automatically restart failed consumer pods once poison offsets have been skipped.
  • Schema Registry Integration: Query the Confluent Schema Registry via io.kestra.plugin.core.http.Request to validate poison record payloads against registered schemas.
  • PagerDuty Incident Escalation: Integrate io.kestra.plugin.pagerduty.notifications.PagerDutyAlert to trigger high-priority on-call pages for persistent consumer group rebalances.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.