When does Helm enforce values.schema.json, and how does it apply to a chart's subcharts?
answer
- Between merging and rendering
- Not only at install time
- Each chart carries its own contract
- The parent's top level holds subchart keys
- Lint validates the chart's own defaults
basics
~20 sHelm validates the coalesced values against values.schema.json before rendering - on install, upgrade, template and lint. Every chart in the dependency tree is checked against its own schema over the slice of values scoped to it, and the failures are reported together.
solid answer
~50 sValidation runs after defaults and overrides are merged and before any template executes, so the schema sees exactly what `.Values` will contain, and a failure aborts the command with no manifests produced. It is not an install-time-only check: `helm upgrade`, `helm template` and `helm lint` apply it too, which is what lets a CI render catch a bad values file without a cluster. The tree is walked chart by chart: a subchart's schema validates the subtree of values scoped to that subchart, and the parent's schema validates the parent's own document - which, at its top level, contains a key per subchart plus `global`. That is the classic trap: closing a parent schema with `additionalProperties: false` without declaring those keys fails every install. `helm lint` validates the chart's own defaults, so a `required` property with no default in values.yaml fails lint. `--skip-schema-validation` disables the check when a vendored subchart's schema is wrong.
code
json · 11 lines{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"additionalProperties": false,
"properties": {
"global": { "type": "object" },
"order-checkout": { "type": "object" },
"payments-ledger": { "type": "object" },
"ingressClassName": { "type": "string" }
}
}go deeper
Know that a chart can ship a values.schema.json and that Helm will refuse to install when your values file breaks it. Reading the failing property path out of the error is the skill expected here.
Explain the ordering - merge, then validate, then render - and name the commands that apply it, including template and lint. Be able to say what a schema failure does and does not leave behind.
Demonstrate the umbrella experience: per-chart recursion, why a closed parent schema breaks on subchart and global keys, why lint fails on a required property with no default, and the narrow cases where skipping validation is defensible.
Own where validation runs across the estate - author CI, consumer CI, or the delivery path - and accept that a check a consumer can turn off with one flag is advisory unless something else enforces it.
### When the check runs A chart's `values.schema.json` is applied at one precise moment: after Helm has coalesced the chart's defaults with everything the caller supplied, and before the first template is executed. That ordering has consequences worth stating out loud. Because validation sees the merged document, a property the schema marks `required` is satisfied whether it came from `values.yaml` or from the caller. And because it runs before rendering, a schema failure produces no manifests and creates no release revision - the command aborts with the offending property paths named per chart. The commands that apply it are the ones that build a values document for a chart: `helm install`, `helm upgrade`, `helm template` and `helm lint`. The `template` case is the operationally valuable one, because it means a CI job that renders a chart with the team's values file validates the schema with no cluster and no credentials. The commands that do not build a values document - `helm show values`, for instance - do not validate anything. ### How subcharts are handled Validation recurses. Helm walks the chart tree and, for each chart that ships a schema, validates that chart against the values scoped to it. A subchart never sees the whole document: it sees the subtree that its parent's values file holds under the subchart's name, merged with the subchart's own defaults and any `global` block, and its schema is evaluated against that. A parent's schema does not reach down into a subchart's keys, and a subchart's schema does not constrain its parent. Failures from several charts are collected and reported together rather than one per run, which matters on a large umbrella - you see all of them in one pass. The trap follows directly. The parent chart's own values document contains, at its top level, a key named for each enabled subchart plus `global`. So writing `"additionalProperties": false` at the root of an 18-chart umbrella's schema without listing every subchart name and `global` as declared properties makes every single install fail, and the error names properties the parent's author never thought of as theirs. The usual resolutions are to declare each subchart key as an open object (`{"type": "object"}`), leaving the subchart's own schema to police its contents, or to keep the root open and close only the objects the parent genuinely owns. ### The lint surprise `helm lint` builds a values document too, from the chart's own `values.yaml` plus any values you pass it. If the schema marks a property `required` and `values.yaml` supplies no default for it, lint fails on a chart that is perfectly correct - the property is meant to come from the caller. Teams hit this the first time they add a schema to a chart in CI. The choices are to give the property a placeholder default, to lint with a representative values file, or to express the requirement in the template with `required` instead so it fires at render time on the real inputs. ### The escape hatch `--skip-schema-validation` turns the check off for a command. The legitimate uses are narrow and worth naming precisely: a vendored third-party subchart whose schema is stricter or simply wrong for a valid configuration you need, and an incident where an over-tight schema is standing between you and a fix. Wiring it into a delivery pipeline as a default is the anti-pattern, because it silently converts every downstream chart's contract into a suggestion, and nobody notices until a values typo ships. If a schema is blocking you regularly, the schema is the defect. ### Practical placement Because the schema is packaged into the `.tgz`, it travels with the chart - a chart published to an OCI registry by CI carries its contract to every consumer, and consumers get validation for free without adopting any tooling. That is the strongest argument for shipping one on an internal platform chart: the check runs on the consumer's machine, in the consumer's pipeline, and at install time, without asking anyone to install anything. The complement is a render job in the chart's own repository: render each chart with a small matrix of representative values files so schema and templates are exercised together on every change. A schema that has drifted behind its templates passes validation and still produces a broken manifest, and only rendering catches that.
- A parent umbrella chart adds `additionalProperties: false` and every install starts failing. Why?The parent's own values document carries a top-level key for each subchart plus `global`, and closing the object makes all of them undeclared properties. Declare each subchart key as an open object and declare `global`, or leave the root open and close only the objects the parent itself owns. The subcharts' contents stay policed by their own schemas either way.
- When is `--skip-schema-validation` the right call?When a vendored subchart's schema rejects a configuration that genuinely works, or during an incident when an over-tight schema blocks a fix. Both are exceptions with a follow-up ticket. Setting it permanently in a pipeline disables every chart's contract at once, including the ones you wrote to catch your own typos.
- Does the schema validate the values stored with an existing release?It validates the document Helm is about to render with. On an upgrade that reuses values recorded on the previous revision, those values become part of the merged document and are validated like any others - so tightening a schema in a new chart version can make an upgrade fail on values that installed cleanly before, which is the right moment to learn about it rather than after rendering.
saying these in an interview costs you the question
- Thinks a parent chart's schema validates subchart values
- Assumes the schema only runs on install
- Believes helm template skips validation since nothing applies
- Closes a parent schema without declaring subchart or global keys
- Treats --skip-schema-validation as a routine pipeline flag
- Expects validation before defaults and overrides merge