Schedule icon
Webhook icon
Assert icon
RedisCLI icon
Docker icon
Script icon
Process icon
Set icon
If icon
Pause icon
Log icon
SlackIncomingWebhook icon

Celery Unacknowledged Task Quarantine and Requeue Guard

Inspects Redis-backed Celery queues for stranded unacknowledged tasks, requeuing recoverable jobs and quarantining poison pills to prevent worker crash loops.

Categories
Infrastructure

In distributed Python backend architectures running on Celery with Redis broker transports, worker nodes are vulnerable to abrupt terminations from Out-Of-Memory (OOM) killer events, spot instance preemptions, hardware reboots, and unhandled segfaults. When a worker process crashes mid-execution, Celery's underlying Kombu transport leaves claimed tasks stranded in Redis unacknowledged data structures (unacked hash and unacked_index sorted set). Under default visibility timeouts, these stranded messages can remain invisible for hours or days, causing business workflows to stall indefinitely. Worse, if a crash was triggered by a poison pill, such as a malformed payload or memory-exhausting payload, subsequent automated redelivery triggers a catastrophic cascade where every surviving worker in the cluster crashes upon claiming the task. This blueprint implements an automated operational guardrail: it interrogates Redis unacknowledged task indexes, evaluates payload headers and retry limits in Python, safely re-injects recoverable tasks into the active queue, quarantines retry-exhausted poison pills to an isolated dead-letter queue behind a human approval gate, verifies post-remediation queue state, and records forensic audit snapshots in Kestra KV storage.

How it works

  1. A schedule trigger or crash webhook initiates the Celery queue inspection.
  2. An Assert task validates that configuration parameters, scan ceilings, and threshold bounds satisfy operational constraints.
  3. An atomic Lua script in io.kestra.plugin.redis.cli.RedisCLI queries Redis unacked and unacked_index, evaluates visibility timestamps against the threshold, decodes message JSON headers, and classifies delivery tags into recoverable items versus retry-exhausted poison pills.
  4. A Python script evaluates trend progression against historical KV records, computes differential metrics, and prepares an itemized remediation manifest.
  5. A KV Set task updates the current snapshot for sequential cycle comparison.
  6. If stranded tasks are detected, an If conditional task branches into remediation processing.
  7. When auto_remediate is enabled and dry_run is false, a Pause task halts execution for human operator sign-off before Redis keys are altered.
  8. Upon operator approval, a remediation Lua script atomically pops target delivery tags from unacked and unacked_index, re-inserts recoverable tasks into the ready queue, and routes poison pills to an isolated dead-letter queue.
  9. A verification Lua script queries Redis to assert that all targeted delivery tags were successfully cleared from unacknowledged structures.
  10. An Assert task verifies that zero targeted tags remain, logging verified counts and persisting complete forensic audit manifests into Kestra KV.
  11. A Slack notification alerts platform engineers with detailed incident metrics.

Architecture diagram

graph TD
    Trigger[Schedule / Webhook Trigger] --> ValidateInputs[Assert: Validate Queue Parameters]
    ValidateInputs --> DetectStalled[RedisCLI: Lua Scan unacked and unacked_index]
    DetectStalled --> EvalTelemetry[Python Script: Classify Recoverable vs Poison Pills]
    EvalTelemetry --> SaveState[KV Set: Update Queue State Snapshot]
    SaveState --> CheckStalled{Stranded Tasks Detected?}
    CheckStalled -- No --> NominalLog[Log: Queue Nominal]
    CheckStalled -- Yes --> CheckMode{Dry Run or Auto Remediate?}
    CheckMode -- Dry Run --> LogPlan[Log: Output Planned Remediation]
    CheckMode -- Auto Remediate --> PauseApproval[Pause: Operator Sign-off Gate]
    PauseApproval --> ExecuteRemediation[RedisCLI: Atomic LPUSH Ready / DLQ and HDEL unacked]
    ExecuteRemediation --> VerifyRemediation[RedisCLI: Assert Delivery Tags Cleared]
    VerifyRemediation --> PostAssert[Assert: Verification Success]
    PostAssert --> SaveAudit[KV Set: Persist Forensic Incident Manifest]
    LogPlan --> SaveAudit
    SaveAudit --> NotifySlack[Slack Webhook: Incident Report]

What you get

  • Proactive detection of stranded Celery tasks stranded in Redis unacknowledged hashes after worker crashes.
  • Automated classification isolating recoverable tasks from retry-exhausted poison pills.
  • Safe operational self-healing atomically requeuing recoverable jobs without restarting Celery broker instances.
  • Worker protection isolating unprocessable poison pills into a dedicated dead-letter queue to halt crash cascades.
  • Human-in-the-loop governance pause gates guaranteeing that automated queue mutations occur only with operator approval.
  • End-to-end verification asserting that remediated delivery tags have been purged from unacknowledged indexes.
  • Forensic audit persistence recording historical snapshots and incident manifests in Kestra KV storage.

Who it's for

  • Python Platform Engineers managing high-throughput Celery worker clusters on Redis.
  • Site Reliability Engineers safeguarding asynchronous task processing against worker OOM crash cascades.
  • DevOps Teams operating distributed Django, FastAPI, and Flask production microservices.
  • Data Operations Engineers ensuring asynchronous ETL tasks do not remain stranded in unacknowledged broker state.

Why orchestrate this with Kestra

  • Native Redis CLI Integration: Executes atomic multi-key Lua scripts directly against Redis without deploying external Python daemons.
  • Human-in-the-Loop Safeguards: Combines dry-run defaults with Kestra Pause tasks to provide safe operator verification before queue alteration.
  • Closed-Loop Verification: Re-reads Redis post-mutation to programmatically assert that unacknowledged indexes are clean before marking workflows successful.
  • Stateful Trend Observability: Leverages Kestra KV storage to correlate stranded task delivery tags across successive audit cycles.
  • Declarative Operations: Encapsulates incident runbooks into Git-versioned workflow code shared across platform engineering teams.

Use cases

  • Worker OOM Incident Recovery: Automatically clears stranded tasks when Kubernetes worker pods are terminated by Linux OOM killer.
  • Poison Pill Crash Loop Prevention: Isolates corrupted task payloads to dead-letter queues before redelivery can crash surviving workers.
  • Visibility Timeout Drift Remediation: Unfreezes tasks stranded by worker network partitions without waiting for multi-hour visibility timeouts.

Inputs

Name Type Default Description
redis_host STRING localhost Hostname or IP address of the target Redis server.
redis_port INT 6379 Port number for the Redis server connection.
redis_password STRING {{ secret('REDIS_PASSWORD') }} Authentication credentials for the Redis instance.
redis_database INT 0 Numeric Redis logical database index used by Celery.
queue_name STRING celery Name of the Celery task queue list in Redis.
stalled_visibility_seconds INT 300 Elapsed duration past visibility timestamp flagging stranded tasks.
max_scan INT 100 Upper bound on unacknowledged delivery tags inspected per pass.
default_max_retries INT 3 Maximum retry threshold classifying poison pills.
quarantine_queue_name STRING celery.quarantine.dead_letter Redis list key where poison-pill tasks are isolated.
dry_run BOOL true Audit only without altering Redis keys when true.
auto_remediate BOOL false Enable automated requeue and quarantine behind approval gate.

Expected outputs

  • {{ outputs.evaluate_task_telemetry.vars.overall_status }}: Status classification (HEALTHY, WARNING, CRITICAL).
  • {{ outputs.evaluate_task_telemetry.vars.stalled_count }}: Count of stranded unacknowledged tasks identified.
  • {{ outputs.evaluate_task_telemetry.vars.requeue_tags }}: List of delivery tags queued for re-insertion into active processing.
  • {{ outputs.evaluate_task_telemetry.vars.quarantine_tags }}: List of poison-pill delivery tags quarantined to dead-letter storage.
  • {{ outputs.remediate_stalled_tasks.vars.command_1 }}: JSON response from remediation Lua execution detailing mutated counts.

Prerequisites

  • Celery application cluster utilizing Redis as broker transport (redis:// scheme).
  • Redis server version 5.0+ with Lua scripting enabled.
  • Network connectivity from Kestra worker nodes to the Redis broker port.
  • Redis password configured under REDIS_PASSWORD secret in Kestra namespace.

Secrets

  • REDIS_PASSWORD: Authentication secret required to connect to the target Redis instance.
  • CELERY_GUARD_WEBHOOK_KEY: Secret API key protecting the on-demand worker crash webhook.
  • SLACK_WEBHOOK_URL: Incoming webhook URL used to dispatch incident notifications.

Quick start

  1. Configure REDIS_PASSWORD, CELERY_GUARD_WEBHOOK_KEY, and SLACK_WEBHOOK_URL in your Kestra namespace secrets.
  2. Confirm your Celery queue name matches queue_name (default is celery).
  3. Trigger a manual execution with dry_run: true to verify connectivity and audit active queue unacknowledged depth.
  4. When stranded tasks are identified, execute with dry_run: false and auto_remediate: true, reviewing the approval modal before applying mutations.
  5. Enable periodic_celery_queue_inspection schedule to establish continuous background surveillance.

Common pitfalls and troubleshooting

  • Redis Key Namespace: Celery prefixes unacknowledged task hashes as unacked and indexes as unacked_index under the configured database index. Verify that redis_database matches your Celery broker_url database path.
  • Visibility Timeout Value: Ensure stalled_visibility_seconds exceeds your Celery configuration's broker_transport_options['visibility_timeout'] to prevent premature requeuing of legitimately running long tasks.
  • Corrupted Message Payloads: If upstream producers push raw strings rather than standard Celery JSON envelopes, the Lua script safely flags them as unparseable and quarantines them to prevent worker exceptions.

How to extend

  • Custom Dead-Letter Notifications: Add an email or PagerDuty dispatch task targeting the on-call platform engineer when poison pills are quarantined.
  • Prometheus Metrics Push: Export stranded task counts and requeue rates to Prometheus Pushgateway for Grafana dashboard visualization.
  • Automated Worker Pod Restart: Trigger a Kubernetes API roll or cloud VM restart task after poison pills are safely quarantined.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.