Skip to content
LatchkeyLatchkey home

kubectl apply --server-side: Field Ownership and Conflicts

kubectl apply --server-side performs Server-Side Apply: the API server merges your manifest and records which manager owns each field.

Server-Side Apply makes ownership explicit, so two controllers (or two pipelines) editing the same object surface a real conflict instead of silently clobbering each other.

What it does

With --server-side, the merge happens on the API server rather than from the local last-applied annotation. Each field is tagged with a field manager. If your apply would overwrite a field owned by a different manager, the server returns a conflict instead of taking the field, unless you pass --force-conflicts.

Common usage

Terminal
kubectl apply --server-side -f deploy.yaml
# claim conflicting fields explicitly
kubectl apply --server-side --force-conflicts -f deploy.yaml
# name the manager so ownership is attributable
kubectl apply --server-side --field-manager=ci-pipeline -f deploy.yaml

Options

FlagWhat it does
--server-sideUse Server-Side Apply (merge on the API server)
--force-conflictsTake ownership of fields currently owned by others
--field-manager=<name>Identify the manager recorded for owned fields
--dry-run=serverRun the apply on the server without persisting
-f, --filenameManifest file or directory to apply

In CI

Set a stable --field-manager per pipeline so conflicts are attributable. When an HPA or another controller owns spec.replicas, drop replicas from your manifest rather than fighting with --force-conflicts, which can fight the autoscaler on every deploy.

Common errors in CI

"Apply failed with N conflicts: conflicts with \"<manager>\" using ...: .spec.replicas" means another manager owns that field; either remove it from your manifest or add --force-conflicts if you really intend to take it. "error: --server-side and --dry-run=client are incompatible" means you combined client dry-run with server-side; use --dry-run=server. Mixing client-side and server-side applies on the same object can leave a stale last-applied annotation.

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

Frequently asked questions

kubectl apply --server-side: Field Ownership and Conflicts?
Server-Side Apply makes ownership explicit, so two controllers (or two pipelines) editing the same object surface a real conflict instead of silently clobbering each other.
What it does?
With --server-side, the merge happens on the API server rather than from the local last-applied annotation. Each field is tagged with a field manager. If your apply would overwrite a field owned by a different manager, the server returns a conflict instead of taking the field, unless you pass --force-conflicts.
In CI?
Set a stable --field-manager per pipeline so conflicts are attributable. When an HPA or another controller owns spec.replicas, drop replicas from your manifest rather than fighting with --force-conflicts, which can fight the autoscaler on every deploy.
Common errors in CI?
"Apply failed with N conflicts: conflicts with \"<manager>\" using ...: .spec.replicas" means another manager owns that field; either remove it from your manifest or add --force-conflicts if you really intend to take it.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card