kubectl replace: Usage, Options & Common CI Errors
Overwrite an object completely - not a merge, a replacement.
kubectl replace swaps a live object for the full manifest you provide, replacing rather than merging. It is the imperative counterpart to apply, used when you want the object to become exactly your file with nothing carried over.
What it does
kubectl replace -f overwrites the existing object with the manifest in one update - fields you omit are removed (unlike apply, which merges). It requires the object to already exist. --force deletes and recreates the object when an in-place replace is not possible (e.g. immutable fields), which is destructive and resets the resourceVersion.
Common usage
kubectl replace -f deploy.yaml
kubectl get deploy/web -o yaml > current.yaml # edit, then:
kubectl replace -f current.yaml
kubectl replace --force -f svc.yaml # delete + recreateCommon errors in CI
"Error from server (NotFound)" because replace will not create. Use apply or create for first-time objects, and replace only to overwrite an existing one. "the object has been modified; please apply your changes to the latest version" means the resourceVersion in your file is stale: replace does an optimistic-concurrency update, so you must replace a freshly fetched object, not an old one. --force is genuinely destructive (it deletes first), so it drops in-flight connections and recreates with a new UID. Never use it casually on stateful or in-service objects in CI.
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