Skip to content

Automation Platform > Deployment & hosting

Self-hosting troubleshooting

Open in ChatGPT ↗
Ask ChatGPT about this page
Open in Claude ↗
Ask Claude about this page
Copied!

Diagnose and fix common problems with self-hosted Automation Platform worker daemons across Docker, Kubernetes, and Direct backends.

Use these checks when the oz-agent-worker daemon won’t start or connect, tasks stay queued, or tasks fail.


Cause: Docker isn’t running, or the daemon platform isn’t supported.

Fix:

  1. Verify Docker is running: docker info.
  2. Confirm the daemon platform is linux/amd64 or linux/arm64. Windows containers are not supported.
  3. If the worker runs inside Docker, confirm the /var/run/docker.sock mount is correct and the mounting user has permission to the socket.

Cause: The worker Deployment couldn’t start, reach the Kubernetes API, or create its preflight Job.

Fix:

  1. Run kubectl describe pod -n NAMESPACE WORKER_POD. Replace NAMESPACE with the chart namespace and WORKER_POD with the worker pod name. For CreateContainerConfigError, verify the Secret and key configured by warp.apiKeySecret.
  2. Check the worker logs for Kubernetes API or preflight diagnostics: kubectl logs -n NAMESPACE WORKER_POD.
  3. Confirm the worker’s namespace has these permissions: create, get, list, watch, delete on jobs; get, list, watch on pods; get on pods/log; list on events.
  4. Confirm the task namespace allows pods with a root init container, unless you enabled native image volumes with kubernetesBackend.useImageVolumes=true.
  5. If your cluster restricts image sources, set kubernetesBackend.preflightImage to an allowlisted image. The default is busybox:1.36.
  6. To pull the preflight image from a private registry, configure imagePullSecrets in kubernetesBackend.podTemplate.

A successful preflight validates the configured pod shape, not task-specific images, Secrets, setup commands, or network access.

Cause: The oz CLI isn’t installed or isn’t on the worker’s PATH.

Fix:

  1. Install the Oz CLI on the worker host. See Installing the CLI.
  2. If the CLI isn’t on PATH, set oz_path in the config file to the absolute path of the oz binary.

Cause: The API key is invalid, expired, or the host cannot reach the Automation Platform‘s backend.

Fix:

  1. Confirm your API key is correct, not expired, and has team scope.
  2. Regenerate the API key in Settings > Cloud platform > API keys if you suspect it’s invalid.
  3. Ensure the host has outbound internet access to oz.warp.dev:443.
  4. Check that no firewall rules are blocking WebSocket connections to wss://oz.warp.dev.
  5. Increase log verbosity with --log-level debug to see connection details.

See Security and networking for the full list of outbound endpoints the worker needs.


Cause: The worker isn’t running, the --host value doesn’t match the worker’s --worker-id, or the worker and task belong to different teams.

Fix:

  1. Confirm the worker is running and connected. Check the worker logs for Successfully connected to server.
  2. Verify the --host (or worker_host) value you passed matches your --worker-id exactly. Case-sensitive.
  3. Ensure the worker’s team matches the team creating the task.

Cause: The worker is running, but metrics do not reach Prometheus or your collector.

Fix:

  1. For Prometheus, confirm OTEL_METRICS_EXPORTER=prometheus, bind to 0.0.0.0 in Docker or Kubernetes, and run curl -s localhost:9464/metrics.
  2. Confirm no firewall or network policy blocks the metrics port.
  3. For OTLP, confirm the collector endpoint is reachable and the protocol is correct.
  4. For Helm, confirm metrics.enabled=true and check the Kubernetes Service or PodMonitor. A PodMonitor requires the Prometheus Operator CRDs.
  5. Restart the worker with --log-level debug and check for metrics errors.

See Monitoring for the full setup guide.


Cause: The task environment, resources, or dependencies failed.

Fix (all backends):

  1. Review task logs in the cloud agent dashboard or via session sharing.
  2. Use --no-cleanup to keep the container, Job, or workspace indefinitely for inspection. With Kubernetes cleanup enabled, failed Jobs remain for 24 hours by default.
  3. Use --log-level debug to see detailed execution logs.
  1. Verify Docker is running (docker info).
  2. If using a custom image, confirm it is glibc-based (not Alpine/musl) and that its architecture matches the worker’s Docker daemon platform.

The Helm chart’s worker.resources configures the worker Deployment, not task Jobs. Task containers have no worker-defined CPU or memory defaults. Configure the task container in kubernetesBackend.podTemplate or use a workload-specific runner instance shape. There is no universal task size; choose values based on the workload’s measured needs.

Start with the Pod state and events:

Terminal window
kubectl get jobs,pods -n NAMESPACE
kubectl describe pod -n NAMESPACE TASK_POD

Replace NAMESPACE with the task namespace and TASK_POD with the task pod name.

Verify: In kubectl describe pod, look for PodScheduled=False, FailedScheduling, Insufficient cpu, or Insufficient memory. Check the Pod’s requests and scheduling constraints against eligible node capacity.

Fix: Right-size requests, lower worker.maxConcurrentTasks, or add compatible capacity. Configure autoscaling for nodes that satisfy the Pod’s selectors, affinity, and tolerations. Raising only a limit does not make a Pending Pod schedulable.

Running container terminates with OOMKilled

Section titled “Running container terminates with OOMKilled”

Verify: Confirm the task container’s termination reason is OOMKilled. Compare peak memory use with its limit, then check Pod events and node pressure.

Fix: Reduce peak memory use or increase task memory in the runner instance shape or pod_template. An instance shape sets the memory request to the same value as the limit, so confirm an eligible node can schedule the larger request.

Verify: Read the Pod reason and events for memory, disk, or node pressure.

Fix: Restore node headroom, reduce concurrency, or add capacity before rerunning the task. For voluntary disruption, see Protect active task pods from disruption.

Exit code 143 generally indicates SIGTERM; it does not prove an out-of-memory failure.

Verify: Check the container termination reason and Pod events for eviction, preemption, node drain, the Job deadline, or manual deletion.

Fix: Address the recorded cause. Treat the failure as OOM only when Kubernetes reports OOMKilled.

  • Image pull errors - Follow Image pull failures. Preflight does not pull every task image.
  • CreateContainerConfigError or FailedMount - Pod events name the missing Secret, ConfigMap, service account, volume, or key.
  • Init container failure - Check each init container’s status and logs. The Warp sidecar-loading init container runs as root unless native image volumes are enabled. Custom init containers must finish before task starts.
  • Network failure - Test DNS, TLS, and the destination from a task Pod, not the worker Pod.
  • Missing task credentials - Provide repository, registry, and application credentials through your approved Secret integration. The worker API key is not a task credential.
  1. Verify the Oz CLI is accessible.
  2. Verify the workspace root directory has write permissions for the user running the worker.

  1. If using a private registry, ensure Docker credentials are available to the worker. See Private Docker registries.
  2. Try pulling the image manually on the worker host: docker pull <image>.
  1. Configure imagePullSecrets in the pod_template section of your worker config.
  2. Verify the Secret exists in the task namespace and contains valid credentials.
  • Verify the image exists and the tag is correct.
  • Check network connectivity from the worker/cluster to the registry.