Skip to main content
DevOps Insightsguides & answers

Terraform · troubleshooting

Error: No value for required variable

A variable in the configuration you are running (the root module) has no default and no value reached it. Terraform could not ask for one, because input is off, as in CI. Usually the .tfvars file was not passed, or the TF_VAR_ environment variable is named differently from the variable.

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 · 9 sections

Before you start

  • The variable's name, and how the job is meant to supply it.

Run this first

step 1 of 1
env | grep '^TF_VAR_'; ls *.tfvars *.tfvars.json 2>/dev/null

Look for Whether the variable's exact name is in any of them

Shows the TF_VAR_ variables that are set and the .tfvars files present. Of those files, only terraform.tfvars and *.auto.tfvars (and their .json forms) are read without -var-file.

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

How is the value meant to arrive?

Cause space

3 of 3 still possible

  • The .tfvars file is not one Terraform loads by itselfCommon
  • The TF_VAR_ environment variable does not match the nameCommon
  • Related: an empty value that passes silentlyOccasional

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

    env | grep '^TF_VAR_'; ls *.tfvars *.tfvars.json 2>/dev/null

    Shows the TF_VAR_ variables that are set and the .tfvars files present. Of those files, only terraform.tfvars and *.auto.tfvars (and their .json forms) are read without -var-file.

    Look for Whether the variable's exact name is in any of them

Every cause, and how to fix it

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

The .tfvars file is not one Terraform loads by itself

Common

Only terraform.tfvars, terraform.tfvars.json and files ending .auto.tfvars or .auto.tfvars.json are loaded automatically. prod.tfvars, dev.tfvars and the like need -var-file.

Confirm

ls *.tfvars *.tfvars.json 2>/dev/null

Your values live in a file with another name

Fix

  • Pass it: terraform plan -input=false -var-file=prod.tfvars (the same for apply).

The TF_VAR_ environment variable does not match the name

Common

TF_VAR_REGION does not set region. A typo, upper case, or a variable renamed in the code but not in the pipeline leaves it unset.

Confirm

env | grep '^TF_VAR_'

A name that differs from the variable block's name

Fix

  • Rename it to TF_VAR_ plus the exact variable name.
export TF_VAR_region=ap-south-1

Reproduced on Terraform 1.14.0; TF_VAR_REGION was ignored.

Related: an empty value that passes silently

Occasional

When a CI secret is missing, TF_VAR_name is often set to an empty string. That counts as a value, so there is no error, and an empty region, tag or name reaches the plan.

Confirm

terraform plan -input=false

A value of "" where you expected a setting

Fix

  • Add a validation block: condition = length(var.NAME) > 0, with an error_message, so an empty value fails loudly.

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

A variable without a default must get a value from somewhere: -var, a .tfvars file, or an environment variable called TF_VAR_ followed by its exact name. When you run Terraform by hand it asks you; in a pipeline it cannot ask, so it stops with this error.

Words used on this page

TF_VAR_name
An environment variable that sets the Terraform variable called name. The part after TF_VAR_ must match exactly, including case.
terraform.tfvars
Read automatically, as are files ending .auto.tfvars. Any other .tfvars file must be named with -var-file.
-input=false
Tells Terraform never to prompt. CI should use it, which is why the error shows up there.
What is actually happening

Reproduced on Terraform 1.14.0 with a variable that has no default: terraform plan -input=false printed Error: No value for required variable, The root module input variable "region" is not set, and has no default value, and the advice to use -var or -var-file.

TF_VAR_region=ap-south-1 fixed it; TF_VAR_REGION did not, because the name after TF_VAR_ is matched exactly. A file called prod.tfvars was ignored until passed with -var-file, while terraform.tfvars and a file ending .auto.tfvars were read without being named.

The silent version is worse: TF_VAR_region set to an empty string, which is what a missing CI secret usually expands to, gave no error at all and planned the value "". A validation block rejecting empty values caught it; nullable = false did not, because an empty string is not null.

How to tell this is your problem
WhereWhat you see
terraform plan or apply -input=falseError: No value for required variable ... The root module input variable "NAME" is not set, and has no default value.
Without -input=false, locallyTerraform prompts var.NAME Enter a value:

How to know it is actually fixed

  • terraform plan -input=false runs and shows the expected value.

Stopping it happening again

  • Run plans with -input=false everywhere, so a missing value fails straight away with this error instead of waiting at a prompt.
  • Add validation blocks to variables that must not be empty.

Security considerations

  • Pass secrets as TF_VAR_ environment variables from your CI's secret store, not with -var on the command line, where they appear in process listings and logs.

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