Trigger icon
Return icon
If icon
Log icon
CompleteJob icon
FailJob icon
SlackIncomingWebhook icon

Camunda 8 Service Task Contract & Retry Backoff Gate

Enforce contract validation, retry backoffs, and incident escalation on Camunda 8 service tasks with Kestra.

Categories
BusinessInfrastructure

In Camunda 8 (Zeebe), distributed business processes rely on external job workers to execute Service Tasks. When an external worker crashes or encounters an unhandled exception without explicitly notifying the Zeebe gateway, the job lock simply expires. Camunda re-delivers the locked job indefinitely without decrementing retries, resulting in a silent zombie loop where no incident is ever raised in Camunda Operate.

This blueprint implements a production-grade Camunda 8 Job Worker and Resilience Gate. It activates service task jobs in real time, validates incoming payload contracts, completes successful tasks with enriched execution variables, applies graduated retry backoffs on transient errors, and explicitly fails invalid jobs with zero retries so operators receive instant incident visibility.

How it works

  1. camunda_job_stream (io.kestra.plugin.camunda.Trigger) acts as an external Zeebe job worker, activating jobs for the specified job_type and acquiring an execution lock for lock_timeout.
  2. validate_payload_contract (io.kestra.plugin.core.debug.Return) verifies that the job's variables fulfill the required business contract (order_id, customer_id, and amount > 0).
  3. route_by_contract_evaluation (io.kestra.plugin.core.flow.If) evaluates the contract result:
    • Valid Contract: Runs fulfillment steps and calls complete_service_task (io.kestra.plugin.camunda.CompleteJob) to report success back to Zeebe with merged variables (fulfillment_status, processed_at), allowing the BPMN token to advance.
    • Invalid Schema: Calls fail_job_permanent_invalid_schema (io.kestra.plugin.camunda.FailJob) with retries: 0. This stops wasteful re-polling and forces Camunda to immediately raise an Incident in Camunda Operate, while alerting Slack.
  4. log_worker_audit (io.kestra.plugin.core.log.Log) logs an immutable record of the job key, process instance key, and outcome.
  5. The flow-level errors block catches unexpected runtime errors and executes fail_job_transient_error (io.kestra.plugin.camunda.FailJob), decrementing retries (retries: trigger.retries - 1) and applying retryBackoff: PT30S so the job cools down before re-activation.

What you get

  • Resilient external worker execution for Camunda 8 BPMN Service Tasks.
  • Automated payload contract validation preventing corrupted state from propagating down the process.
  • Zero-zombie guarantee: locks are never left to expire silently without reporting completion or failure.
  • Exponential / graduated backoff on transient failures to avoid hammer-polling downstream services.
  • Instant incident creation in Camunda Operate when retries are exhausted or data contracts are breached.
  • Real-time Slack notifications directing SREs to the exact job key and process instance key.

Who it's for

  • Platform Engineers and SREs managing Camunda 8 / Zeebe orchestration clusters in production.
  • BPMN Process Developers integrating microservices and third-party APIs via external workers.
  • Integration Teams who need guaranteed error handling and incident visibility for mission-critical workflows.

Why orchestrate this with Kestra

Building external workers as standalone microservices requires writing boilerplate gRPC polling loops, heartbeat handlers, retry state trackers, and error notification hooks. With Kestra, Camunda service tasks become first-class declarative workflows with native secret management, visual execution logs, and automated incident escalation.

Prerequisites

  • A running Camunda 8 / Zeebe cluster (Self-Managed or Camunda SaaS) reachable from Kestra.
  • A BPMN process definition containing a Service Task with task definition type matching job_type (default process-order).
  • A Slack incoming webhook URL for incident alerting.

Secrets

  • SLACK_WEBHOOK_URL: Slack incoming webhook URL used for incident notifications and unhandled worker failures.
  • For Camunda SaaS authentication, optionally configure CAMUNDA_CLIENT_ID and CAMUNDA_CLIENT_SECRET.

Quick start

  1. Configure SLACK_WEBHOOK_URL in your Kestra namespace secrets.
  2. Start a local Camunda 8 Zeebe instance for testing: docker run -d --name zeebe -p 26500:26500 -p 8080:8080 camunda/zeebe:latest
  3. Deploy a sample BPMN process with a Service Task typed process-order.
  4. Start a process instance from the Camunda Modeler or Zeebe CLI with variables: {"order_id": "ORD-1234", "customer_id": "CUST-987", "amount": 250.00}
  5. Enable triggers.camunda_job_stream and verify the job completes and the process advances.

How to extend

  • Add downstream API calls or database updates within the then block before calling CompleteJob.
  • Use io.kestra.plugin.camunda.PublishMessage to correlate messages with other waiting BPMN catch events.
  • Map custom BPMN error codes using Camunda BPMN error events instead of generic failures.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.