| Tested on | Ubuntu 26.04 LTS (Resolute Raccoon) |
|---|---|
| Package | terraform 1.15.8-1 |
| Applies to | Any host with Terraform installed |
| Lab environment | Single Ubuntu VM with Terraform — Terraform lab environment on Ubuntu |
| Privilege | Normal user |
| Scope | Troubleshooting Terraform undeclared variable errors — Reference to undeclared input variable versus Value for undeclared variable, missing variable blocks, extra terraform.tfvars keys, -var and -var-file mistakes, root versus child module scope, name diagnostics, and validate-plan verification. Does not cover full input-variable precedence across CLI, env, and HCP layers. |
| Related guides | Terraform variables Terraform module input and output terraform validate terraform plan Terraform troubleshooting |
Terraform reports undeclared variable problems in two different shapes. The fix depends on which message you see:
Reference to undeclared input variableversus:
Value for undeclared variableThe first means configuration references var.something that was never declared in that module. The second means a value arrived from terraform.tfvars, -var, or -var-file for a name the module does not know about.
Each scenario uses its own directory under ~/terraform-labs/terraform-undeclared-variable-error/. Examples use built-in terraform_data only.
validate or plan. This article does not walk the full variable precedence ladder — see Terraform variables when multiple assignment sources disagree.
Two undeclared variable error types
| Message | What happened | Typical source |
|---|---|---|
| Reference to undeclared input variable | HCL uses var.name with no matching variable block |
main.tf, module argument, expression |
| Value for undeclared variable | A value was assigned to a name the module never declared | terraform.tfvars, -var, -var-file |
Extra tfvars keys surface as a warning when plan loads the assignment file. Wrong -var names fail at plan time with an error, often paired with No value for required variable, because the CLI assignment is evaluated when Terraform binds input variables for that run.
Fix a missing variable block
Configuration references var.environment but no variable block exists yet.
mkdir -p ~/terraform-labs/terraform-undeclared-variable-error/errors/missing-declaration
cd ~/terraform-labs/terraform-undeclared-variable-error/errors/missing-declarationWrite the broken configuration:
cat > main.tf <<'EOF'
terraform {
required_version = ">= 1.12.0"
}
resource "terraform_data" "label" {
input = "env-${var.environment}"
}
EOFvalidate stops on the undeclared reference before plan can run:
terraform validate -no-colorError: Reference to undeclared input variable
on main.tf line 6, in resource "terraform_data" "label":
6: input = "env-${var.environment}"
An input variable with the name "environment" has not been declared. This
variable can be declared with a variable "environment" {} block.Add a declaration in variables.tf:
variable "environment" {
type = string
}The fixed tree lives in fixes/missing-declaration/. Move there first:
cd ~/terraform-labs/terraform-undeclared-variable-error/fixes/missing-declarationThe new variable block should clear validation:
terraform validate -no-colorSuccess! The configuration is valid.Supply the variable on the command line:
terraform plan -no-color -input=false -var='environment=prod'Plan: 1 to add, 0 to change, 0 to destroy.
# terraform_data.label will be created
+ resource "terraform_data" "label" {
+ input = "env-prod"
}The reference and the declaration now share the same name in the same module scope.
Fix tfvars with an undeclared variable
A terraform.tfvars key does not create a variable — it only assigns one that already exists.
mkdir -p ~/terraform-labs/terraform-undeclared-variable-error/errors/extra-tfvars
cd ~/terraform-labs/terraform-undeclared-variable-error/errors/extra-tfvarsDeclare only name but assign environment in tfvars:
cat > main.tf <<'EOF'
resource "terraform_data" "label" {
input = var.name
}
EOFAdd the lone declared variable in variables.tf:
cat > variables.tf <<'EOF'
variable "name" {
type = string
}
EOFThe extra environment key lives in terraform.tfvars:
cat > terraform.tfvars <<'EOF'
name = "demo"
environment = "prod"
EOFTerraform accepts the configuration itself, but when plan loads terraform.tfvars it warns that environment was assigned even though the root module never declared that variable:
terraform plan -no-color -input=falsePlan: 1 to add, 0 to change, 0 to destroy.
# terraform_data.label will be created
+ resource "terraform_data" "label" {
+ input = "demo"
}
Warning: Value for undeclared variable
The root module does not declare a variable named "environment" but a value
was found in file "terraform.tfvars". If you meant to use this value, add a
"variable" block to the configuration.Either remove the stray key from terraform.tfvars or declare environment and use it. The fix in fixes/extra-tfvars/ adds:
variable "environment" {
type = string
}and changes the resource input to "${var.name}-${var.environment}". After that, plan shows input = "demo-prod" with no undeclared-variable warning.
Fix -var and -var-file errors
When the variable block exists but the CLI name is wrong, Terraform reports Value for undeclared variable for the mistyped name and No value for required variable for the real one.
mkdir -p ~/terraform-labs/terraform-undeclared-variable-error/errors/wrong-cli-var
cd ~/terraform-labs/terraform-undeclared-variable-error/errors/wrong-cli-varRequired sensitive variable with no default:
cat > main.tf <<'EOF'
resource "terraform_data" "label" {
input = var.api_token
}
EOFDeclare the sensitive token variable separately:
cat > variables.tf <<'EOF'
variable "api_token" {
type = string
sensitive = true
}
EOFHyphens are not underscores — api-token is a different name:
terraform plan -no-color -input=false -var='api-token=secret'Error: Value for undeclared variable
A variable named "api-token" was assigned on the command line, but the root
module does not declare a variable of that name. To use this value, add a
"variable" block to the configuration.
Error: No value for required variable
on variables.tf line 1:
1: variable "api_token" {
The root module input variable "api_token" is not set, and has no default
value. Use a -var or -var-file command line argument to provide a value for
this variable.Use the declared name with straight ASCII quotes:
terraform plan -no-color -input=false -var='api_token=secret'Plan: 1 to add, 0 to change, 0 to destroy.
# terraform_data.label will be created
+ resource "terraform_data" "label" {
+ input = (sensitive value)
}Curly quotes from copied forum text produce the same undeclared-name error with a nearly invisible character in the reported name:
terraform plan -no-color -input=false -var="$(printf '%b' '\342\200\234api_token=secret\342\200\235')"Error: Value for undeclared variable
A variable named "“api_token" was assigned on the command line, but the root
module does not declare a variable of that name.Re-type the flag manually with straight quotes, or use -var-file with a plain-text file you control. The verify/ directory plans successfully with:
terraform plan -no-color -input=false -var-file=terraform.tfvarsRoot versus child module variables
Child-module variables and root-module variables live in separate scopes. Passing a value requires a module argument; referencing var.app_name at the root requires a root variable block.
mkdir -p ~/terraform-labs/terraform-undeclared-variable-error/errors/module-scope/modules/app
cd ~/terraform-labs/terraform-undeclared-variable-error/errors/module-scopeChild module expects app_name:
cat > modules/app/main.tf <<'EOF'
variable "app_name" {
type = string
}
resource "terraform_data" "app" {
input = var.app_name
}
EOFRoot calls the module without the required argument:
cat > main.tf <<'EOF'
terraform {
required_version = ">= 1.12.0"
}
module "app" {
source = "./modules/app"
}
EOFInitialize before validating module calls:
terraform init -input=falseWith the child module on disk, validate reports the missing module argument:
terraform validate -no-colorError: Missing required argument
on main.tf line 5, in module "app":
5: module "app" {
The argument "app_name" is required, but no definition was found.Pass the value at the call site in fixes/module-scope/:
module "app" {
source = "./modules/app"
app_name = "demo"
}A different mistake looks like Reference to undeclared input variable — root passes app_name = var.app_name but never declares variable "app_name" at the root. See errors/module-scope-alt-root-var/ in the lab tree for that variant. Child modules cannot read root variables unless you pass them in as arguments.
Diagnose variable names
When the error names a variable you thought you declared, check these in order:
- Spelling —
api_tokenversusapi-tokenversusapitoken - Case —
Environmentandenvironmentare different names - Hyphen versus underscore — CLI flags and HCL names must match the
variableblock exactly - Module scope —
var.nameinside a child module refers to that module'svariables.tf, not the root - Assignment source — confirm the value comes from the file or flag you expect (
terraform.tfvars,*.auto.tfvars,-var-file,-var) - Root declaration — module arguments that reference
var.xstill needvariable "x"in the root module
terraform console can confirm a variable is in scope after you fix declarations — see terraform console for quick expression checks.
Verify the fix
The verify/ directory combines declared variables with a tfvars file:
cd ~/terraform-labs/terraform-undeclared-variable-error/verifyConfirm configuration is valid:
terraform validate -no-colorSuccess! The configuration is valid.Plan with the tfvars file:
terraform plan -no-color -input=false -var-file=terraform.tfvarsPlan: 1 to add, 0 to change, 0 to destroy.
# terraform_data.label will be created
+ resource "terraform_data" "label" {
+ input = "demo-prod"
}Destroy lab resources when finished:
terraform destroy -auto-approve -input=false 2>/dev/null || trueDiagnostic checklist
| Symptom | Likely cause | Fix |
|---|---|---|
| Reference to undeclared input variable | var.x in HCL, no variable block |
Add variable "x" in the same module |
| Value for undeclared variable warning | Extra key in terraform.tfvars, *.auto.tfvars, or explicit -var-file |
Declare the variable or remove/fix the key |
| Value for undeclared variable error | Wrong variable name passed with -var |
Match the declared variable name exactly |
| No value for required variable | Name correct but no assignment | Add -var, tfvars, or a default |
| Missing required argument on module | Child input not passed from root | Add app_name = ... to the module block |
Undeclared var.x in module argument |
Root variable never declared | Add root variable "x" or pass a literal |
References
- Input variables — HashiCorp Developer
- Assigning values to root module variables — HashiCorp Developer
- terraform validate command — HashiCorp Developer
Summary
Terraform splits undeclared variable failures into two families. Reference to undeclared input variable means HCL mentions var.name without a variable block in that module — add the declaration or fix the reference. Value for undeclared variable means an assignment arrived from tfvars or the CLI for a name the module never declared — align the key with a real variable block or stop passing the extra value.
Extra terraform.tfvars keys warn when plan loads the assignment file, while wrong -var names fail at plan with an error and a paired No value for required variable message. Watch for hyphen versus underscore and curly quotes copied from documentation.
Module calls add a third pattern: Missing required argument when a child-module input is not passed from the root. Root and child variables are separate scopes — pass values through module arguments and declare root variables when module blocks reference var.x.
After fixes, terraform validate should be clean (or only show warnings you intend to address), and terraform plan with your tfvars or -var flags should bind every required input. For broader variable assignment patterns, continue with Terraform variables.

