ConnectorStatusTrigger icon
Schedule icon
Assert icon
ConnectorGetStatus icon
ConnectorGetOffsets icon
Get icon
Script icon
Set icon
If icon
Produce icon
Log icon
Pause icon
Request icon
ConnectorAlterOffsets icon
ConnectorResume icon
SlackIncomingWebhook icon

Kafka Connect Sink Poison Pill Offset Rewind and Skip Gate

Detect Kafka Connect poison pill crashes, isolate bad records to DLQ, safely rewind or skip committed offsets with approval, and verify recovery via KIP-875.

Categories
DataInfrastructure

Production Apache Kafka streaming architectures rely heavily on Kafka Connect to stream events from Kafka topics into relational databases, search engines, and data lakes via sink connectors (such as JDBC Sink, Elasticsearch Sink, OpenSearch Sink, or Snowflake Sink). When a consumer task encounters a poison pill record, such as an unparseable byte sequence, schema mismatch, or foreign key constraint violation, the task crashes and enters FAILED state.

Because Kafka Connect sink tasks process records in strict offset order, standard automated restarts simply re-read the exact same poison pill record, causing immediate recursive task crashes. Ingestion on that partition completely halts, consumer lag mounts, and downstream systems fall out of sync. Until Apache Kafka 3.6 (KIP-875), modifying a connector's committed offsets required taking down the Connect cluster and manually mutating the internal connect-offsets topic.

This blueprint implements an automated end-to-end recovery guard for Kafka Connect that detects crashed sink tasks, verifies stationary committed offsets against historical telemetry in Kestra KV, publishes diagnostic poison pill records to a dead-letter quarantine topic, safely advances (SKIP_POISON_RECORD) or rewinds (REWIND_OFFSET) committed partition offsets using native KIP-875 offset management behind an operator approval gate, and verifies that the connector recovers to a healthy RUNNING state.

How it works

  1. Configuration Pre-Flight Assertion: validate_inputs (io.kestra.plugin.core.execution.Assert) validates operational parameters, ensuring positive rewind counts, valid thresholds, and non-empty connector names.
  2. Connector Status Inspection: get_connector_status (io.kestra.plugin.kafka.ConnectorGetStatus) queries the Kafka Connect REST API, extracting the overall connector state (RUNNING, FAILED, PAUSED), active worker IDs, task states, and stack traces.
  3. Committed Offset Collection: get_connector_offsets (io.kestra.plugin.kafka.ConnectorGetOffsets) retrieves the committed partition offsets for all assigned partitions via KIP-875 GET /connectors/{name}/offsets.
  4. Historical State Diffing: load_previous_offset_state (io.kestra.plugin.core.kv.Get) retrieves previous run offset snapshots from Kestra KV store under kafka_connect_offset_tracker_{connector_name}.
  5. Triage & Offset Calculation: triage_poison_pill_and_compute_offsets (io.kestra.plugin.scripts.python.Script) parses task traces, correlates stalled offsets across execution runs, identifies stuck partitions, formats a dead-letter quarantine manifest, and calculates target remediation offsets based on the selected policy (SKIP_POISON_RECORD advances the failing offset by 1, REWIND_OFFSET rewinds by N records).
  6. KV Telemetry Persistence: persist_offset_tracker_kv (io.kestra.plugin.core.kv.Set) writes the updated offset progression and stall telemetry back to the Kestra KV store.
  7. Quarantine Dead-Letter Publishing: When enabled, publish_poison_pill_to_dlq (io.kestra.plugin.kafka.Produce) sends a structured diagnostic record containing the connector name, partition, poison offset, and full exception stack trace to the designated Kafka quarantine topic.
  8. Authorized Remediation with Approval Gate: When dry_run is disabled:
    • Execution pauses at approval_gate (io.kestra.plugin.core.flow.Pause) for operator verification.
    • Upon approval, stop_connector (io.kestra.plugin.core.http.Request) invokes PUT /connectors/{name}/stop to place the connector in STOPPED state as strictly required by KIP-875.
    • alter_connector_offsets (io.kestra.plugin.kafka.ConnectorAlterOffsets) overwrites committed offsets with the computed target offsets via PATCH /connectors/{name}/offsets.
    • resume_connector (io.kestra.plugin.kafka.ConnectorResume) issues PUT /connectors/{name}/resume to restart tasks from the newly applied offsets.
  9. Post-Remediation Verification: The workflow re-queries ConnectorGetOffsets and ConnectorGetStatus, asserting that the connector state returned to RUNNING without failing again.
  10. Incident Notification: dispatch_slack_notification (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) delivers a structured operational summary to Slack.

What you get

  • Automated detection of Kafka Connect sink partition stalls and poison pill task crashes.
  • Elimination of recursive task crash loops without manual cluster restarts or internal topic surgery.
  • Isolated dead-letter quarantine records published to Kafka with exact partition, offset, and error traces.
  • First-class KIP-875 offset manipulation supporting single-record skipping (SKIP_POISON_RECORD) or multi-message rewind (REWIND_OFFSET).
  • Human approval gate (Pause) and non-destructive dry-run simulation mode to prevent accidental data loss.
  • Post-remediation verification confirming that new offsets are committed and worker tasks are running cleanly.
  • Persistent historical telemetry in Kestra KV store for audit compliance and trend analysis.

Who it's for

  • Streaming Platform Engineers and SREs maintaining Apache Kafka and Kafka Connect clusters.
  • Data Engineers running CDC ingestion pipelines (Debezium, JDBC Sink, Snowflake Sink, OpenSearch Sink).
  • Incident Response teams triaging streaming consumer lag spikes and crashed Connect workers.

Why orchestrate this with Kestra

Kafka Connect provides no built-in mechanism to automatically pause, skip poison pill offsets, and resume failed sink connectors. Handling this with ad-hoc scripts requires fragile curl commands against internal REST APIs, lacks state persistence between runs, has no built-in pause-and-resume approval mechanisms, and risks offset corruption if an operator modifies offsets while a connector is still running.

Orchestrating this workflow with Kestra delivers a declarative blueprint with atomic Kestra KV state tracking, native Kafka Connect plugin tasks, built-in approval gates, guaranteed STOPPED state lifecycle compliance, automated dead-letter publishing, and comprehensive Slack triage alerting.

Prerequisites

  • Apache Kafka Connect cluster (version 3.6 or higher supporting KIP-875 offset management) reachable from Kestra.
  • An accessible Apache Kafka cluster hosting source/sink topics and the quarantine topic.
  • Target sink connector deployed on Kafka Connect.
  • A Slack Incoming Webhook URL configured in Kestra secrets.

Secrets

  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL for incident triage notifications and execution alerts.

Quick start

  1. Configure SLACK_WEBHOOK_URL in your Kestra namespace secrets.
  2. Set connect_url and bootstrap_servers to match your Kafka environment.
  3. Specify the target connector name in connector_name (e.g. orders-jdbc-sink).
  4. Run an initial manual execution with dry_run: true to record an offset baseline and inspect connector health.
  5. When a poison pill crash occurs, review the triage summary, set dry_run: false, and approve the approval_gate to alter offsets and recover the connector.
  6. Enable the on_connector_failure status trigger and periodic_offset_guard schedule for continuous automated protection.

How to extend

  • Automated DLQ Consumer & Notification: Wire an io.kestra.plugin.kafka.Consume task to inspect quarantined poison records and dispatch schema diffs to data governance channels.
  • Source Connector Support: Extend the triage script to adjust source connector partition keys (such as filename and position for file connectors, or table and incrementing for JDBC sources).
  • PagerDuty Escalation: Integrate io.kestra.plugin.pagerduty.notifications.PagerDutyAlert when consecutive poison pill crashes exceed critical thresholds.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.