camzabriskie.com

Primers › Kubernetes

Kubernetes object size limits

01 / 02 updated Oct 9, 2026
On this page
  1. A few terms
  2. Where the limit is checked
  3. The rendered size is the size that counts
  4. Helm’s release record hits the same limit
  5. Ways to get under the limit
  6. References

A Helm upgrade fails with this message:

Error: UPGRADE FAILED: cannot patch "app-settings" with kind ConfigMap:
ConfigMap "app-settings" is invalid: []: Too long: may not be more than 1048576 bytes

1,048,576 is 1024 × 1024, so the limit is 1 MiB. Kubernetes refused to store the object because it’s too big. Nothing is wrong with Helm, the pod, or the node, and retrying won’t help. The object has to get smaller.

A few terms

Where the limit is checked

Every object passes the same check on its way into the cluster. During a Helm upgrade, two kinds of object go through it: the ones your chart defines, and a record Helm keeps about the release itself.

Both kinds of object pass the same check. Helm saves its release record before it applies the chart's objects, so a release record that's too big fails the upgrade before any of them change.

The check adds up the values under data (and binaryData, for a ConfigMap), not the keys or the YAML around them, and compares the total with 1,048,576 bytes [6]. etcd has limits of its own, which the 1 MiB check stays safely under: by default it accepts requests up to 1.5 MiB and stores up to 2 GiB in total, with 8 GiB as the suggested maximum [7]. That total is why lots of objects that each fit can still cause trouble together.

The rendered size is the size that counts

The object Kubernetes checks is the one Helm produces from the templates, not any file you edited. Templates can repeat their input, so a modest values file can render into an object far bigger than anything in the repo:

Nobody edited a file anywhere near 1 MiB. The loop did the multiplying, and only the rendered object shows it.

To see the real size, render just the suspect template and count its bytes:

macOS / Linux

helm template ./chart -f values.yaml --show-only templates/settings-configmap.yaml | wc -c

Windows (PowerShell)

$out = helm template ./chart -f values.yaml --show-only templates/settings-configmap.yaml | Out-String
[Text.Encoding]::UTF8.GetByteCount($out)

helm template renders the chart locally without touching the cluster, and --show-only keeps just the one file [8]. wc -c counts bytes. In PowerShell, Out-String joins the output into one string [9] and GetByteCount counts the bytes it takes as UTF-8 [10]. Either way the count includes the YAML around the data, so it reads a little high, and a number under 1,048,576 is safely under the limit.

Helm’s release record hits the same limit

Helm keeps a record of every release revision, and by default that record is a Secret in the release’s namespace, holding the contents of the chart and the values [11]. Its name follows the pattern sh.helm.release.v1.<release>.v<revision> [12]. Being a Secret, it gets the same 1 MiB check, and the error names that Secret instead of your ConfigMap.

Two details change how this one behaves:

For release records that really are that large, Helm documents a beta sql storage backend that keeps them in a database instead of the cluster [11].

Ways to get under the limit

OptionFits whenCost
Shrink the templateA loop repeats a large blockOften the cheapest fix, so look here first
Split into several ConfigMapsThe content separates cleanly, such as per componentMore objects, each mounted separately
Mount a volume or use an object storeThe data is large reference data, not settingsA storage dependency and a loading step
Fetch at startupThe data changes independently of deploysPods depend on that source to start

Moving the data to a Secret doesn’t help. Kubernetes doesn’t compress Secrets, and the base64 you see in a Secret’s YAML is only how the bytes are written down: the check counts the decoded bytes under data, against the same 1,048,576 [15]. Helm’s release record is smaller than its contents only because Helm compresses it before saving it.

Compressing the data yourself

Helm gets its release record under the limit by compressing it, and an app can do the same with its own data: gzip it, store the compressed bytes under the ConfigMap’s binaryData, which holds raw bytes rather than text [2], and decompress it when it’s read. At least one product documents this as its answer to the limit. Airlock Microgateway accepts zstd, gzip, or zip files as binaryData in its ConfigMaps, warns that decompressing costs extra resources, and recommends it only for a ConfigMap that would otherwise be over the limit [16].

That works there because the gateway was built to decompress its own config. For your own app, nothing in Kubernetes decompresses anything, so the app or a startup step has to do it, and I haven’t found a source covering that in general. It also only helps if the data compresses well, and diffs of compressed bytes stop being readable in review.

The Kubernetes docs point the same way for settings larger than the limit: a mounted volume, a database, or a file service [2]. Start with the template, though. If the rendered output holds the same block many times, include it once and reference it, and the object may drop well under the limit with no change to how the app works.

References

Show all 16 sourcesHide sources
  1. [1] ↩ a b The Kubernetes Authors, “Kubernetes Components,” Kubernetes Documentation. Accessed: Oct. 9, 2026. [Online]. Available: https://kubernetes.io/docs/concepts/overview/components/
  2. [2] ↩ a b c The Kubernetes Authors, “ConfigMaps,” Kubernetes Documentation. Accessed: Oct. 9, 2026. [Online]. Available: https://kubernetes.io/docs/concepts/configuration/configmap/
  3. [3] ↩ The Kubernetes Authors, “Secrets,” Kubernetes Documentation. Accessed: Oct. 9, 2026. [Online]. Available: https://kubernetes.io/docs/concepts/configuration/secret/
  4. [4] ↩ a b The Helm Authors, “Introduction to Helm,” Helm Documentation. Accessed: Oct. 9, 2026. [Online]. Available: https://helm.sh/docs/intro/introduction/
  5. [5] ↩ The Helm Authors, “Using Helm,” Helm Documentation. Accessed: Oct. 9, 2026. [Online]. Available: https://helm.sh/docs/intro/using_helm/
  6. [6] ↩ The Kubernetes Authors, “pkg/apis/core/validation/validation.go (ValidateConfigMap),” kubernetes/kubernetes, GitHub repository, commit ef06af9. Accessed: Oct. 9, 2026. [Online]. Available: https://github.com/kubernetes/kubernetes/blob/ef06af9b9d09e8dc0eb1cc0768b0b542f35549bb/pkg/apis/core/validation/validation.go#L8204-L8232
  7. [7] ↩ The etcd Authors, “System limits,” etcd v3.5 Documentation. Accessed: Oct. 9, 2026. [Online]. Available: https://etcd.io/docs/v3.5/dev-guide/limit/
  8. [8] ↩ The Helm Authors, “helm template,” Helm Documentation. Accessed: Oct. 9, 2026. [Online]. Available: https://helm.sh/docs/helm/helm_template/
  9. [9] ↩ Microsoft, “Out-String,” PowerShell 7.6 Documentation. Accessed: Oct. 9, 2026. [Online]. Available: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/out-string
  10. [10] ↩ Microsoft, “Encoding.GetByteCount Method,” .NET API Reference. Accessed: Oct. 9, 2026. [Online]. Available: https://learn.microsoft.com/en-us/dotnet/api/system.text.encoding.getbytecount
  11. [11] ↩ a b The Helm Authors, “Storage backends,” Helm Documentation, Advanced Helm Techniques. Accessed: Oct. 9, 2026. [Online]. Available: https://helm.sh/docs/topics/advanced/
  12. [12] ↩ The Helm Authors, “pkg/storage/storage.go (makeKey),” helm/helm, GitHub repository, commit dc56a44. Accessed: Oct. 9, 2026. [Online]. Available: https://github.com/helm/helm/blob/dc56a44fee5ac036807348bc48653bc93d714953/pkg/storage/storage.go#L339-L341
  13. [13] ↩ The Helm Authors, “pkg/action/upgrade.go,” helm/helm, GitHub repository, commit dc56a44. Accessed: Oct. 9, 2026. [Online]. Available: https://github.com/helm/helm/blob/dc56a44fee5ac036807348bc48653bc93d714953/pkg/action/upgrade.go#L408-L470
  14. [14] ↩ The Helm Authors, “pkg/storage/driver/util.go (encodeRelease),” helm/helm, GitHub repository, commit dc56a44. Accessed: Oct. 9, 2026. [Online]. Available: https://github.com/helm/helm/blob/dc56a44fee5ac036807348bc48653bc93d714953/pkg/storage/driver/util.go#L36-L58
  15. [15] ↩ The Kubernetes Authors, “pkg/apis/core/validation/validation.go (ValidateSecret),” kubernetes/kubernetes, GitHub repository, commit ef06af9. Accessed: Oct. 9, 2026. [Online]. Available: https://github.com/kubernetes/kubernetes/blob/ef06af9b9d09e8dc0eb1cc0768b0b542f35549bb/pkg/apis/core/validation/validation.go#L8101-L8115
  16. [16] ↩ Ergon Informatik AG, “ConfigMaps size limit,” Airlock Microgateway 4.7 Documentation. Accessed: Oct. 9, 2026. [Online]. Available: https://docs.airlock.com/microgateway/4.7/index/1730261073553.html

Every source cited across the primers is collected on one page.