Skip to main content
DevOps Insightsguides & answers

Terraform · troubleshooting

Error: Reference to undeclared input variable

The configuration reads var.NAME, but the module it is in has no variable block with that name. Usually a typo, or a child module using a variable only the root module declares.

Reproduced on Terraform 1.14.0, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 8 sections

Before you start

  • The file and line in the error, and which directory (module) that file is in.

Run this first

step 1 of 1
terraform validate

Look for The file path: it tells you which module needs the declaration

Reports every undeclared reference without needing credentials or state.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

What does the error message say after has not been declared?

Cause space

4 of 4 still possible

  • The name is misspelledCommon
  • A child module uses a variable that only the root module declaresCommon
  • The value is set in a .tfvars file but never declaredOccasional
  • It is a local value, or the declaration is in a file Terraform does not readOccasional

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    terraform validate

    Reports every undeclared reference without needing credentials or state.

    Look for The file path: it tells you which module needs the declaration

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

The name is misspelled

Common

var.regoin instead of var.region, or a name changed in the variable block but not everywhere it is used.

Confirm

terraform validate

Did you mean "…"? in the error message

Fix

  • Use the declared name, or rename every reference along with the variable block.

A child module uses a variable that only the root module declares

Common

Modules do not inherit variables. The error points into the module's directory, for example ../modules/app/main.tf.

Confirm

grep -rn 'variable "NAME"' --include='*.tf' .

A declaration only in the root directory, not in the module the error points to

Fix

  • Declare variable "NAME" {} inside the module, then pass the value in the module block: NAME = var.NAME.
# modules/app/variables.tf
variable "env" {
  type = string
}

# root main.tf
module "app" {
  source = "../modules/app"
  env    = var.env
}

Reproduced on Terraform 1.14.0: with both parts in place, validate succeeds.

The value is set in a .tfvars file but never declared

Occasional

A .tfvars file only assigns values. Without a variable block the value is ignored and plan warns Value for undeclared variable.

Confirm

terraform plan -input=false

Warning: Value for undeclared variable naming the same variable

Fix

  • Add a variable block with that name, with a type and description.

It is a local value, or the declaration is in a file Terraform does not read

Occasional

A locals value must be read as local.NAME. A variables.tf in a subdirectory, or saved with another extension, is not part of the module.

Confirm

ls *.tf *.tf.json
grep -rn 'NAME' --include='*.tf' .

The name in a locals block, or a declaration outside the module's directory

Fix

  • Read locals as local.NAME.
  • Move the variable block into a .tf file in the same directory as the code that uses it.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

In Terraform, var.something only works if the same module, meaning the same directory, declares variable "something". Setting a value in a .tfvars file does not declare it, and a module cannot see its parent's variables. Declare the variable where it is used, or fix the name.

Words used on this page

Module
All the .tf files in one directory. The directory you run Terraform in is the root module; directories called with a module block are child modules.
Input variable
A value declared with a variable block and read as var.NAME, only inside the module that declares it.
Local value
A value from a locals block, read as local.NAME, not var.NAME.
What is actually happening

Reproduced on 23 October 2026 with Terraform 1.14.0. terraform validate printed Error: Reference to undeclared input variable with the file and line, then either Did you mean "region"? when a declared name was close, or This variable can be declared with a variable "env" {} block.

Five different mistakes produced the same error: a misspelled name; a child module using a variable that only the root module declares; a value present only in terraform.tfvars; a locals value read as var.NAME; and a variable block saved in a subdirectory. Terraform reads only the .tf and .tf.json files in the module's own directory, and the HashiCorp docs treat nested directories as separate modules.

With the value only in terraform.tfvars, terraform plan also printed Warning: Value for undeclared variable before the error. That warning names the missing declaration.

How to tell this is your problem
WhereWhat you see
terraform validate, plan or applyError: Reference to undeclared input variable … An input variable with the name "NAME" has not been declared.
terraform plan, with a .tfvars fileWarning: Value for undeclared variable

How to know it is actually fixed

  • terraform validate prints Success! The configuration is valid.

Stopping it happening again

  • Run terraform validate in CI on every change, for each root module.
  • Keep each module's variable blocks in its own variables.tf, and pass values to child modules explicitly.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it