# kubectl create job: Usage, Options & Common CI Errors

> kubectl create job runs a one-off Job, optionally from a CronJob template. Triggering migrations in CI, waiting for completion, and the AlreadyExists error.

Source: https://latchkey.dev/learn/command-reference/kubectl-create-job  
Updated: 2026-06-25

Kick off a one-off Job - or trigger a CronJob on demand.

kubectl create job creates a single Job, either from an image or from an existing CronJob's template. In CI it is the idiomatic way to run a database migration or a one-shot task and gate on its result.

## What it does

kubectl create job NAME --image=IMG runs a one-off Job; --from=cronjob/NAME copies a CronJob's pod template so you trigger it immediately without waiting for its schedule. Pair it with kubectl wait --for=condition=complete to block until the Job finishes.

## Common usage

```Terminal
kubectl create job migrate --image=myreg/app:${GIT_SHA} -- ./migrate.sh
kubectl create job run-now --from=cronjob/nightly-report
kubectl wait --for=condition=complete job/migrate --timeout=300s
kubectl logs job/migrate
```

## Common errors in CI

"AlreadyExists" on a fixed Job name is the re-run trap - append a unique suffix (the build number or git SHA) so each run gets its own Job, or delete the prior Job first. A Job that fails is not surfaced by create itself; you must kubectl wait --for=condition=complete (which times out non-zero on failure) and read the pod logs - a green create is not a green Job. The Job's backoffLimit means it may retry several times before reporting failed, so set a generous wait --timeout. Use --for=jsonpath to distinguish complete from failed if you need to branch.

## Using this in CI

A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.

```Terminal
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods

# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info

# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes
```

> Always set `--request-timeout` in CI. Without it an unreachable API server hangs until the job times out, which turns a thirty-second failure into a twenty-minute one.

## FAQ

### kubectl create job: Usage, Options & Common CI Errors?

kubectl create job creates a single Job, either from an image or from an existing CronJob's template. In CI it is the idiomatic way to run a database migration or a one-shot task and gate on its result.

### What it does?

kubectl create job NAME --image=IMG runs a one-off Job; --from=cronjob/NAME copies a CronJob's pod template so you trigger it immediately without waiting for its schedule. Pair it with kubectl wait --for=condition=complete to block until the Job finishes.

### Common errors in CI?

"AlreadyExists" on a fixed Job name is the re-run trap - append a unique suffix (the build number or git SHA) so each run gets its own Job, or delete the prior Job first. A Job that fails is not surfaced by create itself; you must kubectl wait --for=condition=complete (which times out non-zero on failure) and read the pod logs - a green

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
