cdktf deploy fails with "Missing variable" even though the variable has a default value
Covers the cdktn/CDKTF deploy-time error where a variable with a null default is still reported missing, and how to satisfy it with a TF_VAR_ environment variable or an explicit value. Use when cdktf deploy exits complaining about a missing variable that appears to have a default. Not for synth-time errors or variables missing from cdktf.json.
TL;DR
Export the variable explicitly: export TF_VAR_mirror="[value]" (using your variable name), then re-run cdktf deploy. A null default does not count as "provided" when the module requires a value at deploy time.
The error
Missing variable: 'mirror'. You can provide it using the 'TF_VAR_mirror' environment variable.Fix it
- Identify the variable name in the error (
mirrorhere). - Provide it via the environment:
export TF_VAR_mirror="your-value"(or prefix it inline:TF_VAR_mirror="your-value" cdktf deploy). - Alternatively pass it through your stack code by assigning the TerraformVariable a concrete value instead of relying on the null default.
- Re-run
cdktf deployand confirm the plan phase starts.
Expected result: deploy proceeds past variable validation into plan/apply.
When to use this
cdktf deploy(ordeploy --skip-synth) exits 1 with "Missing variable" for a variable you thought had a default- The default is
nulland the consuming module treats null as unset
When NOT to use this
cdktf synthitself fails (that is a code/binding problem, not a variable problem)- The variable is genuinely undeclared anywhere (add the TerraformVariable construct first)
Root cause
A null default in CDKTF/Terraform means "no value" rather than "a usable value". When the module or provider configuration requires the variable at apply time, Terraform still reports it missing because null satisfies nothing. The deploy path validates variables before planning, so the failure appears even though synth succeeded.
Edge cases
TF_VAR_names are case-sensitive and must match the variable name exactly.- In CI, set the variable as a pipeline secret/env var rather than hardcoding it.
--skip-synthskips code re-execution but not variable validation; the error can appear on skip-synth runs too.