kubectl replace

Replace a resource by filename or stdin. The resource must already exist, and the entire object is replaced with the new definition.

kubectl replace -f [FILE] [flags]

Common Flags

FlagShortDescription
--filename-fFilename, directory, or URL to file to use to replace the resource
--forceDelete and recreate the resource if it cannot be updated in place
--cascadeMust be background, foreground, or orphan. Used with --force
--grace-periodGrace period for deletion when using --force
--save-configSave the configuration in the annotation for future apply usage
--validateValidate the input before sending (default true)

Examples

Replace a resource from a file

kubectl replace -f deployment.yaml

Force replace a resource (delete and recreate)

kubectl replace -f deployment.yaml --force

Replace from stdin

kubectl get deployment my-app -o yaml | sed 's/nginx:1.25/nginx:1.26/' | kubectl replace -f -

Replace with grace period for force delete

kubectl replace -f pod.yaml --force --grace-period=0

Replace and save config for future apply usage

kubectl replace -f deployment.yaml --save-config

When to Use kubectl replace

kubectl replace performs a full replacement of a resource. Unlike kubectl apply, which merges changes, replace sends the complete object definition to the API server. The existing resource is entirely overwritten with the provided specification. This makes replace predictable but potentially destructive if your local manifest is incomplete.

Replace vs Apply

The key distinction is how each command handles existing fields:

# Apply: merges changes, preserves fields you don't specify
kubectl apply -f deployment.yaml

# Replace: overwrites everything with exactly what's in the file
kubectl replace -f deployment.yaml

With apply, if a controller set an annotation or an HPA changed the replica count, those fields are preserved. With replace, any field not in your file is removed. This means you need a complete, up-to-date manifest.

The Get-Modify-Replace Workflow

The safest way to use replace is the get-modify-replace pattern:

# Get the current state
kubectl get deployment my-app -o yaml > deployment.yaml

# Edit the file
vim deployment.yaml

# Replace with the modified version
kubectl replace -f deployment.yaml

This ensures your replacement manifest includes all current fields, minimizing the risk of accidentally removing controller-managed fields.

Pipe-Based Replacement

You can combine get and replace through a pipe for quick inline changes:

# Update an image inline
kubectl get deployment my-app -o yaml | \
  sed 's|image: nginx:1.25|image: nginx:1.26|' | \
  kubectl replace -f -

# Add a label inline
kubectl get deployment my-app -o yaml | \
  yq '.metadata.labels.version = "v2"' | \
  kubectl replace -f -

This pattern is useful in scripts where you need to modify a specific field programmatically.

Force Replace

When you need to change immutable fields, --force deletes and recreates the resource:

# Force replace when immutable fields have changed
kubectl replace -f service.yaml --force

# Force replace with no grace period (immediate deletion)
kubectl replace -f pod.yaml --force --grace-period=0

Force replace causes downtime because the resource is deleted before the new version is created. For Services, this means the ClusterIP changes unless you specify it explicitly. For Deployments, the pods are terminated and recreated.

When Replace Is Appropriate

Replace is the right choice in these scenarios:

  • Atomic updates: When you want to ensure the resource matches your manifest exactly, with no merged remnants from previous configurations.
  • Immutable field changes: When you need to change fields that cannot be updated in place, such as Job selectors or PVC storage class.
  • Controlled overwrites: When you explicitly want to remove fields that were added by controllers or manual edits.
  • CI/CD with complete manifests: When your pipeline always generates complete resource definitions and you want deterministic outcomes.
# CI/CD pipeline using replace for deterministic deployments
kubectl get deployment my-app &>/dev/null && \
  kubectl replace -f deployment.yaml || \
  kubectl create -f deployment.yaml

Resource Version Conflicts

Replace uses the resourceVersion field for optimistic concurrency. If the resource was modified between your get and replace, the replace fails with a conflict error:

# This might fail if someone else modified the resource
kubectl replace -f deployment.yaml
# error: the object has been modified; please apply your changes to the latest version

# Solution: get the latest version and try again
kubectl get deployment my-app -o yaml > deployment.yaml
# Make your changes again
kubectl replace -f deployment.yaml

This conflict detection prevents accidental overwrites of concurrent changes.

Best Practices

Prefer kubectl apply for most workflows because it is safer with the three-way merge. Use replace only when you need full resource replacement semantics. Always base your replacement manifest on the current live state using kubectl get -o yaml. Avoid --force in production unless you understand the downtime implications. If you use replace in CI/CD, ensure your manifests are always complete and up to date.

Interview Questions About This Command

What is the difference between kubectl replace and kubectl apply?
replace overwrites the entire resource with the provided definition, removing any fields not in the new spec. apply performs a three-way merge that preserves fields managed by other actors. replace requires the resource to exist already.
When would you use kubectl replace --force?
When a resource has immutable fields that need to change (like a Job's selector or a Service's clusterIP). --force deletes the resource and recreates it. This causes downtime for the resource.
Why might kubectl replace remove fields you did not intend to delete?
Because replace sends the entire object definition. If you omit a field from your YAML, it is removed from the resource. This includes fields added by controllers, admission webhooks, or previous manual edits.

Common Mistakes

  • Using replace without realizing it overwrites the entire resource, removing fields that were set by controllers or other tools.
  • Using --force on production services without understanding it causes downtime during the delete-recreate cycle.
  • Applying a stale YAML file with replace that is missing fields added since the file was last updated.

Related Commands