kubectl annotate: Usage, Options & Common CI Errors
By Daniel Zoghalchali·Latchkey
Attach metadata that tools read but selectors ignore.
kubectl annotate sets free-form key/value metadata on an object. Unlike labels, annotations are not used for selection - they carry information for controllers, tooling, and humans, including the change-cause shown in rollout history.
What it does
kubectl annotate RESOURCE NAME key=value adds an annotation; key- removes it and --overwrite replaces an existing one - identical ergonomics to kubectl label. Annotations have no value-format restrictions and a generous size budget, so they hold things labels cannot (URLs, JSON, descriptions).
Like label, re-running without --overwrite fails with "already has a value ... and --overwrite is false" - add --overwrite for idempotent pipelines. The total annotations payload is capped at 256 KB; stuffing a large file into an annotation triggers "metadata.annotations: Too long". Note that kubectl apply stores its prior state in the kubectl.kubernetes.io/last-applied-configuration annotation, so very large manifests can approach that limit - prefer --server-side apply, which does not use that 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 annotate: Usage, Options & Common CI Errors?
kubectl annotate sets free-form key/value metadata on an object. Unlike labels, annotations are not used for selection - they carry information for controllers, tooling, and humans, including the change-cause shown in rollout history.
What it does?
kubectl annotate RESOURCE NAME key=value adds an annotation; key- removes it and --overwrite replaces an existing one - identical ergonomics to kubectl label. Annotations have no value-format restrictions and a generous size budget, so they hold things labels cannot (URLs, JSON, descriptions).
Common errors in CI?
Like label, re-running without --overwrite fails with "already has a value ... and --overwrite is false" - add --overwrite for idempotent pipelines. The total annotations payload is capped at 256 KB; stuffing a large file into an annotation triggers "metadata.annotations: Too long".