# linkerd inject: Add Proxies to Manifests

> linkerd inject adds the Linkerd proxy sidecar annotation to Kubernetes manifests. Reference for --manual, --enable-debug-sidecar, and the injection errors in CI.

Source: https://latchkey.dev/learn/command-reference/linkerd-inject  
Updated: 2026-06-30

linkerd inject rewrites Kubernetes manifests to add the Linkerd proxy-injection annotation (or, with --manual, the full sidecar).

Piping manifests through linkerd inject before apply is the standard way to mesh a workload from CI, and it is easy to diff so reviewers see exactly what changed.

## What it does

linkerd inject reads Kubernetes YAML and adds the linkerd.io/inject: enabled annotation to pod templates so the proxy-injector webhook adds the sidecar at admission. With --manual it injects the full proxy container directly instead of relying on the webhook.

## Common usage

```Terminal
linkerd inject deployment.yaml | kubectl apply -f -
# inject a whole directory
cat ./k8s/*.yaml | linkerd inject - | kubectl apply -f -
# re-inject after a proxy upgrade
kubectl get deploy my-app -o yaml | linkerd inject - | kubectl apply -f -
```

## Options

| Flag | What it does |
| --- | --- |
| --manual | Inject the sidecar directly instead of the annotation |
| --enable-debug-sidecar | Add the debug container for troubleshooting |
| --ignore-inbound-ports <p> | Ports the proxy should not intercept inbound |
| --ignore-outbound-ports <p> | Ports to skip on outbound |
| -o yaml | Print the injected manifest (the default) |

## In CI

Run linkerd inject in the deploy stage and pipe straight to kubectl apply. Verify the result with linkerd check --proxy afterward. Re-run inject when you upgrade Linkerd so proxies pick up the new version.

## Common errors in CI

"Error: could not inject ... no supported resources found" means the input had no Deployment/Pod/StatefulSet to inject. A resource that reports "injection skipped" already has the annotation or is a kind inject leaves alone. If the sidecar never appears after apply, the proxy-injector webhook is down, which linkerd check surfaces.

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

### linkerd inject: Add Proxies to Manifests?

Piping manifests through linkerd inject before apply is the standard way to mesh a workload from CI, and it is easy to diff so reviewers see exactly what changed.

### What it does?

linkerd inject reads Kubernetes YAML and adds the linkerd.io/inject: enabled annotation to pod templates so the proxy-injector webhook adds the sidecar at admission. With --manual it injects the full proxy container directly instead of relying on the webhook.

### In CI?

Run linkerd inject in the deploy stage and pipe straight to kubectl apply. Verify the result with linkerd check --proxy afterward. Re-run inject when you upgrade Linkerd so proxies pick up the new version.

### Common errors in CI?

"Error: could not inject ... no supported resources found" means the input had no Deployment/Pod/StatefulSet to inject. A resource that reports "injection skipped" already has the annotation or is a kind inject leaves alone. If the sidecar never appears after apply, the proxy-injector webhook is down, which linkerd check surfaces.

---

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
