kubectl replace --force: Usage, Options & Common CI Errors
Delete and recreate a resource to get past an immutable field.
kubectl replace overwrites a resource wholesale, and with --force it deletes then recreates the object - the escape hatch for changing immutable fields that apply and patch cannot touch. It is powerful and destructive, so it is a last resort.
What it does
kubectl replace -f overwrites the live object entirely with your manifest (unlike apply's merge). --force makes it delete the existing object and create it anew, which is the only way to change immutable fields such as a Job's selector, a Service's clusterIP, or some PVC fields - at the cost of a real delete/recreate.
Common usage
kubectl replace -f deploy.yaml
kubectl replace --force -f job.yaml # recreate to change a Job selector
kubectl get svc/web -o yaml | <edit clusterIP> | kubectl replace --force -f -Common errors in CI
Plain replace fails with "the object has been modified" if your manifest's resourceVersion is stale, or "field is immutable" when you change a field that needs recreation - that is the signal to use --force. But --force deletes the object first, so it drops Service endpoints, cluster IPs, and any data the object guarded; for a stateful resource that means downtime or loss - never --force a production database PVC or StatefulSet casually. Prefer apply/patch for normal changes and reserve replace --force for test fixtures or genuinely immutable-field changes, gating on rollout status afterwards.
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.
# 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