← docs index · ← cloud-deployment.md
Symptoms-first reference for operators running iterion in cloud mode (Helm chart, docker-compose, or any setup using Mongo + NATS + S3-compatible blob storage). For each symptom: how to diagnose, what to check, what fixes it.
For deployment / install instructions see cloud-deployment.md. For exposing iterion publicly see cloud-public-exposure-checklist.md.
# Server-side health
curl -fsS http://<server-host>:4891/healthz
curl -fsS http://<server-host>:4891/readyz
curl -fsS http://<server-host>:4891/metrics | head -20
# Runner pool status (Kubernetes)
kubectl -n <ns> get pods -l app.kubernetes.io/component=runner
kubectl -n <ns> logs -l app.kubernetes.io/component=runner --tail=200
# Queue depth (NATS)
nats stream info iterion-runs
nats consumer info iterion-runs iterion-runners
# Mongo connectivity from server pod
kubectl -n <ns> exec deploy/iterion-server -- nc -zv <mongo-host> 27017
# Blob bucket connectivity from server pod
kubectl -n <ns> exec deploy/iterion-server -- aws --endpoint-url $S3_ENDPOINT s3 ls s3://$S3_BUCKET/runs/
If /readyz returns 503: the server can reach itself but cannot reach Mongo, NATS, or blob storage. The body lists which probe failed.
status: queued for minutes)Probable cause: no runner pod is consuming the NATS queue, OR runner is consuming but cannot acquire the lock, OR runner is consuming but cannot reach Mongo / blob.
Diagnose:
kubectl get pods -l app.kubernetes.io/component=runner — replicas > 0?nats consumer info iterion-runs iterion-runners — Num Pending decreasing? Num Outstanding Acks non-zero?kubectl logs -l app.kubernetes.io/component=runner --tail=200 | grep -E 'lock|claim|mongo|blob'Fix:
kubectl describe scaledobject iterion-runner for KEDA controller errors.ErrLockHeld in logs and Nak the message. Expected — JetStream redelivers. If all runners loop on ErrLockHeld, the run was leased and orphaned; wait for the 60s TTL or nats kv del iterion-locks <run-id> to force release.running past their max_durationProbable cause: runner pod was terminated mid-run (OOM, eviction, node drain), the lease expired, but no other runner picked it up; OR the engine lost its sandbox container without aborting.
Diagnose:
iterion inspect --run-id <id> --events | tail -50 (or kubectl logs … | grep <id>) — last event before hang?nats kv get iterion-locks <run-id> — is the lease still claimed?kubectl get events -n <ns> --sort-by='.lastTimestamp' | tail -30 — pod evictions, OOM kills?Fix:
status: running in lease but no runner pod alive): release with nats kv del iterion-locks <run-id> and the next runner will pick the run up via JetStream redelivery. The engine resumes from the last checkpoint.runner.resources.limits.memory in your values overlay; some workflows (especially claude_code with long context) need ≥ 2 GiB.docker ps --filter ancestor=ghcr.io/socialgouv/iterion-sandbox-slim from the runner host shows lingering containers. Restart the runner pod; the engine drains and recreates sandboxes per run./readyz 503 with mongo: connection refusedProbable cause: server cannot reach Mongo at the configured ITERION_MONGO_URI.
Diagnose:
kubectl exec deploy/iterion-server -- env | grep MONGOkubectl exec deploy/iterion-server -- nc -zv <mongo-host> 27017kubectl get networkpolicy -n <ns> — does the egress allow port 27017 to the Mongo namespace?Fix:
ITERION_MONGO_URI and roll the deployment.ITERION_MONGO_URI=mongodb+srv://...?tls=true&retryWrites=true./readyz 503 with blob: AccessDeniedProbable cause: S3 credentials are wrong, the bucket doesn’t exist, or the bucket policy denies the iterion server.
Diagnose:
kubectl exec deploy/iterion-server -- env | grep -E 'S3|AWS'aws --endpoint-url $S3_ENDPOINT s3 ls s3://$S3_BUCKET/Fix:
ITERION_S3_ACCESS_KEY_ID / ITERION_S3_SECRET_ACCESS_KEY and roll the deployment.s3:GetObject, s3:PutObject, s3:DeleteObject, s3:ListBucket on the configured bucket.serviceAccount.annotations.eks.amazonaws.com/role-arn in your values overlay and unset the *_ACCESS_KEY_ID env vars.Probable cause: the WebSocket endpoint cannot reach MongoSource (when in cloud mode with NATS-driven runs), OR the JWT used by the studio lacks the right tenant scope, OR a proxy strips WS upgrade headers.
Diagnose:
Upgrade: websocket. Does the handshake return 101?kubectl logs deploy/iterion-server | grep -E 'eventstream|ws|tenant'iterion inspect --run-id <id> --events from a TTY against the same store: do events exist?Fix:
nginx.ingress.kubernetes.io/proxy-set-header: "Upgrade $http_upgrade".ITERION_MODE=cloud is set on the server. Without it, runview.service defaults to FilesystemSource which won’t see Mongo events.budget_exceeded immediatelyProbable cause: the workflow’s max_cost_usd / max_tokens is below the cost of the first node call.
Diagnose:
iterion inspect --run-id <id> --events | grep -E 'budget|cost'.bot source’s budget: block.Fix:
budget: block (max_cost_usd / max_tokens) and resume the run; iterion has no per-run CLI override for these caps.max_iterations too — a low cap forces premature termination.iterion bench asymptote shows all runs at iteration 0Probable cause: the --judge-node flag does not match a node ID actually present in the workflow, OR no EventEdgeSelected events are emitted (no loop-back edges in the workflow).
Diagnose:
iterion inspect --run-id <id> --events | grep -E 'edge_selected|node_finished' | head -20iterion validate <workflow.bot> — confirm node IDs match what --judge-node expects.Fix:
judge / agent in the .bot source (e.g. judge reviewer: → --judge-node reviewer).-> as loop_name(N) edges), the bench has nothing to iterate over. Add a loop or measure a different recipe.Probable cause: a dependency (Go module, npm package, or base image layer) has a newly-published HIGH-severity advisory. The Trivy workflow publishes SARIF and summaries; it does not fail PRs by itself unless your repository adds a separate hard gate through code scanning or branch protection.
Diagnose:
trivy fs --severity HIGH,CRITICAL . locally to reproduce.Fix:
go get -u <module>@<version> then go mod tidy.iterion-sandbox-slim tag. The release pipeline emits a new tag every Monday..trivyignore entry with a justification comment. Don’t bypass without one — drift is how compliance findings accumulate.manifests version driftProbable cause: the CI guard saw a mismatch between charts/iterion/Chart.yaml appVersion and package.json version.
Diagnose:
git show HEAD -- charts/iterion/Chart.yaml package.jsonFix:
task chart:sync-version (bumps Chart.yaml to match package.json) and recommit.If a symptom isn’t covered above and /readyz looks healthy:
iterion report --run-id <id> --output report.md.kubectl logs ... > /tmp/iterion-logs.txt.