# kind load docker-image: Load Local Images

> kind load docker-image pushes a locally built image into the kind nodes so pods can run it without a registry. Reference for the subcommands and ImagePullBackOff fixes.

Source: https://latchkey.dev/learn/command-reference/kind-load-image  
Updated: 2026-06-30

kind load docker-image <image> copies a locally built image into every kind node, so pods reference it directly with no registry push.

A kind cluster cannot see images on your host Docker by default. kind load copies a freshly built image into the nodes, the key step between docker build and kubectl apply in CI.

## What it does

kind load has two forms: `docker-image <name>` copies an image already in the host Docker daemon into the nodes, and `image-archive <tar>` loads a saved tarball. After loading, set `imagePullPolicy: IfNotPresent` (or Never) so the kubelet uses the local copy.

## Common usage

```Terminal
docker build -t myapp:test .
kind load docker-image myapp:test --name ci
# or from a saved archive
docker save myapp:test -o app.tar
kind load image-archive app.tar --name ci
```

## Options

| Form | What it does |
| --- | --- |
| load docker-image <name> | Copy a host image into the nodes |
| load image-archive <tar> | Load a docker save tarball |
| --name | Target cluster (default "kind") |
| --nodes | Load into specific nodes only |

## In CI

The order matters: build, then `kind load docker-image`, then apply. Use a unique tag per run (a commit SHA) so the kubelet never serves a stale cached layer with the same tag. Set `imagePullPolicy: IfNotPresent` so it does not try to pull from a registry.

## Common errors in CI

`ImagePullBackOff` / `ErrImagePull` with `:latest` happens because the default pull policy for latest is Always; tag a specific version and set `imagePullPolicy: IfNotPresent`. `image: "myapp:test" not present locally` means the build tag and the load name differ. `ERROR: no nodes found for cluster "ci"` means the cluster name is wrong or not created.

## 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

### kind load docker-image: Load Local Images?

A kind cluster cannot see images on your host Docker by default. kind load copies a freshly built image into the nodes, the key step between docker build and kubectl apply in CI.

### What it does?

kind load has two forms: docker-image <name> copies an image already in the host Docker daemon into the nodes, and image-archive <tar> loads a saved tarball. After loading, set imagePullPolicy: IfNotPresent (or Never) so the kubelet uses the local copy.

### In CI?

The order matters: build, then kind load docker-image, then apply. Use a unique tag per run (a commit SHA) so the kubelet never serves a stale cached layer with the same tag. Set imagePullPolicy: IfNotPresent so it does not try to pull from a registry.

### Common errors in CI?

ImagePullBackOff / ErrImagePull with :latest happens because the default pull policy for latest is Always; tag a specific version and set imagePullPolicy: IfNotPresent. image: "myapp:test" not present locally means the build tag and the load name differ.

---

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
