# Kustomize commonAnnotations

> The commonAnnotations field adds annotations to every resource. Reference for the field, template propagation, and the overwrite behavior to watch in CI.

Source: https://latchkey.dev/learn/command-reference/kustomize-common-annotations  
Updated: 2026-06-30

commonAnnotations adds a fixed set of annotations to every resource the build produces.

Annotations carry non-identifying metadata: a build number, a commit SHA, an ownership tag. commonAnnotations stamps them across an overlay in one place.

## What it does

commonAnnotations adds the given key/value pairs to metadata.annotations on every resource and into pod template annotations. Unlike labels, annotations are not used for selection, so there is no selector-immutability concern. Existing annotation keys with the same name are overwritten.

## Common usage

```kustomization.yaml
commonAnnotations:
  app.kubernetes.io/managed-by: kustomize
  example.com/git-sha: "abc1234"
  example.com/build: "ci-2026-06-30"
```

## Behavior

| Aspect | Effect |
| --- | --- |
| metadata.annotations | Pairs added to every resource |
| pod template annotations | Propagated into spec.template |
| existing same-key annotation | Overwritten by the common value |
| selectors | Not affected (annotations are not selectors) |

## In CI

Inject the commit SHA via kustomize edit set annotation or by templating the value before build, so each deploy is traceable to a commit. Annotation values must be strings, so quote numeric-looking values like a build number to avoid YAML parsing them as integers.

## Common errors in CI

"cannot unmarshal number into Go value of type string" means an unquoted numeric annotation value; wrap it in quotes. "metadata.annotations: Too long: must have at most 262144 bytes" means the total annotation size exceeds the limit, often from accidentally stuffing a whole file into a value. Overwritten annotations are silent, so do not rely on commonAnnotations to preserve a pre-existing value.

## 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
```

> Always set `--request-timeout` in CI. Without it an unreachable API server hangs until the job times out, which turns a thirty-second failure into a twenty-minute one.

## FAQ

### Kustomize commonAnnotations?

Annotations carry non-identifying metadata: a build number, a commit SHA, an ownership tag. commonAnnotations stamps them across an overlay in one place.

### What it does?

commonAnnotations adds the given key/value pairs to metadata.annotations on every resource and into pod template annotations. Unlike labels, annotations are not used for selection, so there is no selector-immutability concern. Existing annotation keys with the same name are overwritten.

### In CI?

Inject the commit SHA via kustomize edit set annotation or by templating the value before build, so each deploy is traceable to a commit. Annotation values must be strings, so quote numeric-looking values like a build number to avoid YAML parsing them as integers.

### Common errors in CI?

"cannot unmarshal number into Go value of type string" means an unquoted numeric annotation value; wrap it in quotes. "metadata.annotations: Too long: must have at most 262144 bytes" means the total annotation size exceeds the limit, often from accidentally stuffing a whole file into a value.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
