New to Kestra?
Use blueprints to kickstart your first workflows.
A Kestra blueprint that watches Kubernetes pods stuck in ImagePullBackOff or ErrImagePull and alerts on Slack with the likely cause, without spamming.
list_pods (io.kestra.plugin.scripts.shell.Commands) dumps the namespace's pods as JSON with kubectl.find_stuck (io.kestra.plugin.scripts.python.Script) looks at every container state and collects pods stuck in ImagePullBackOff or ErrImagePull. For each one it guesses the cause from the waiting message, the image name, and the pod's pull secrets: registry rate limiting, auth failures, a private registry with no imagePullSecrets, or a probable typo when the image has never been seen. It compares against the KV state so only newly stuck pods alert.maybe_alert (io.kestra.plugin.core.flow.If) posts the Slack alert only when there is something new, naming the pod, the exact image, how long it has been stuck, and the likely cause.save_state (io.kestra.plugin.core.kv.Set) writes back the current stuck list. Recovered pods drop out on their own, so getting stuck again alerts again, and steady-state reruns stay quiet.Anyone running workloads on Kubernetes who has stared at ImagePullBackOff wondering whether it is a typo, a secret, or the registry. Works on any cluster you can reach with a client certificate: minikube, kind, managed clusters.
kubectl get pods shows you the symptom; this flow adds the diagnosis, the memory, and the notification in one scheduled place. Kestra holds the cluster credentials as secrets, keeps every run's findings where you can audit them, and the KV state means the second run does not page you about the same pod again.
| Secret | What it is |
|---|---|
CLIENT_CRT |
base64-encoded client certificate from your kubeconfig |
CLIENT_KEY |
base64-encoded client key from your kubeconfig |
MASTERURL |
base64-encoded Kubernetes API server URL, reachable from inside the Kestra container |
SLACK_WEBHOOK |
base64-encoded Slack Incoming Webhook URL |
In Kestra OSS, secrets come from environment variables prefixed with SECRET_ and must be base64-encoded. If the API URL uses 127.0.0.1 or localhost, replace it with host.docker.internal so the Kestra container can reach it.
SECRET_ environment variables.namespace: if a pod is stuck pulling, the Slack alert names it, the image, and the likely cause.kubectl describe output by shelling out per stuck pod.| Input | Type | Default | What it does |
|---|---|---|---|
namespace |
STRING | default |
the namespace whose pods to watch |
slack_webhook |
STRING | (required) | Incoming webhook URL of the Slack channel for alerts |
kubectl describe pod.