# kubectl attach: Usage, Options & Common CI Errors

> kubectl attach connects to a running container's process streams. How it differs from exec, and the connection-upgrade and detach-key gotchas in CI.

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

Connect to the container's main process - not a new shell.

kubectl attach hooks your terminal up to the streams of a container's existing main process (PID 1), unlike exec which starts a new process. It is useful for interacting with a program that reads stdin or to watch live output.

## What it does

kubectl attach POD connects to the running container's stdout/stderr (and stdin with -i, TTY with -t). Because it attaches to PID 1 rather than spawning a process, it is the right tool when the container runs an interactive program expecting input - and the wrong tool when you just want a shell (use exec for that).

## Common usage

```Terminal
kubectl attach my-pod                      # watch the main process output
kubectl attach -it my-pod                  # interact with its stdin/TTY
kubectl attach -it my-pod -c app           # a specific container
```

## Common errors in CI

attach is rarely right for CI: with no TTY, -t hangs the step, and attaching to a process that ignores stdin gives you nothing useful. "unable to upgrade connection" means the SPDY/websocket upgrade to the kubelet failed (network policy, proxy stripping the upgrade header) - the same cause as the exec variant. The detach sequence is Ctrl-P Ctrl-Q, not Ctrl-C (which would signal the process); a script that pipes Ctrl-C to "detach" actually kills PID 1 and the pod. Prefer kubectl logs -f for non-interactive output and exec for shells.

## 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 attach: Usage, Options & Common CI Errors?

kubectl attach hooks your terminal up to the streams of a container's existing main process (PID 1), unlike exec which starts a new process. It is useful for interacting with a program that reads stdin or to watch live output.

### What it does?

kubectl attach POD connects to the running container's stdout/stderr (and stdin with -i, TTY with -t). Because it attaches to PID 1 rather than spawning a process, it is the right tool when the container runs an interactive program expecting input - and the wrong tool when you just want a shell (use exec for that).

### Common errors in CI?

attach is rarely right for CI: with no TTY, -t hangs the step, and attaching to a process that ignores stdin gives you nothing useful. "unable to upgrade connection" means the SPDY/websocket upgrade to the kubelet failed (network policy, proxy stripping the upgrade header) - the same cause as the exec variant.

---

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
