kubectl annotate: Usage, Options & Common CI Errors
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).
Common usage
kubectl annotate deploy/web kubernetes.io/change-cause="deploy ${GIT_SHA}"
kubectl annotate svc/web prometheus.io/scrape="true"
kubectl annotate pod my-pod description="debug fixture" --overwrite
kubectl annotate pod my-pod description- # removeCommon 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". 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.