Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Terraform By James Joyner IV · · 9 min read

Terraform Error Guide: 'No value for required variable' (input variable is not set)

Fix Terraform's 'No value for required variable' error: pass values via tfvars, -var, or TF_VAR_ env, add sensible defaults, and wire variables correctly in CI.

  • #terraform
  • #troubleshooting
  • #errors
  • #variables

Exact Error Message

Error: No value for required variable

  on variables.tf line 3:
   3: variable "region" {

The root module input variable "region" is not set, and has no default value.
Use a -var or -var-file command line argument to provide a value for this
variable.

In automation, where interactive prompts are disabled, the same root cause surfaces with -input=false:

Error: No value for required variable

  on variables.tf line 9:
   9: variable "db_password" {

The root module input variable "db_password" is not set, and has no default
value. Use a -var or -var-file command line argument to provide a value for
this variable, or set the input variable's "default" attribute to provide a
default value.

What the Error Means

A variable block with no default is a required input. Terraform must obtain a value for it from somewhere before it can plan. When you run interactively, Terraform prompts you. When no value is supplied and prompting is disabled (CI, -input=false, or a non-TTY), the run fails with No value for required variable.

The fix is always to deliver the value through one of Terraform’s input channels, or to give the variable a default so it is no longer required. Which channel to use depends on whether the value is a secret, environment-specific, or a safe constant.

Common Causes

  • Missing -var or -var-file — you expected to pass it on the command line and forgot.
  • Missing TF_VAR_ environment variable — the value was meant to come from TF_VAR_region but the variable is unset in the shell or CI job.
  • Required variable in non-interactive context — CI runs with -input=false, so Terraform cannot prompt.
  • Typo in the tfvars filenameterraform.tfvars is auto-loaded, but prod.tfvars is not unless you pass -var-file, and *.auto.tfvars must end exactly in .auto.tfvars.
  • Variable declared in a child module but not passed — the module declares it as required, and the calling module block omits it.
  • Wrong workspace/directoryterraform.tfvars exists, but you ran Terraform from a directory where it is not loaded.

How to Reproduce the Error

Declare a required variable and run a non-interactive plan without supplying it:

# variables.tf
variable "region" {
  type        = string
  description = "AWS region to deploy into"
}
terraform plan -input=false
Error: No value for required variable

  on variables.tf line 2:
   2: variable "region" {

The root module input variable "region" is not set, and has no default value.

Diagnostic Commands

List every required variable (those without a default) so you know exactly what must be supplied:

grep -B1 -A4 'variable ' *.tf | grep -L default
terraform console <<<'var.region'

Check what tfvars files exist and which are auto-loaded — only terraform.tfvars and *.auto.tfvars load automatically:

ls -1 *.tfvars *.auto.tfvars 2>/dev/null

Confirm whether the value is coming from the environment:

env | grep '^TF_VAR_'

Run a plan that reports the resolved value without applying:

terraform plan -var-file=prod.tfvars

Step-by-Step Resolution

1. Pass the value on the command line for one-off runs:

terraform plan -var="region=us-east-1"

2. Put environment-specific values in a tfvars file and load it explicitly:

# prod.tfvars
region   = "us-east-1"
db_name  = "orders"
terraform plan -var-file=prod.tfvars

3. Use auto-loaded names when you want zero flags. Terraform loads terraform.tfvars and any file ending in .auto.tfvars automatically:

mv prod.tfvars prod.auto.tfvars
terraform plan

4. Supply secrets through TF_VAR_ environment variables so they never sit in a file:

export TF_VAR_db_password="$(vault kv get -field=password secret/db)"
terraform plan

5. Wire CI explicitly. In a non-interactive pipeline, set the env vars or pass -var-file, and keep -input=false so a missing value fails loudly instead of hanging:

TF_VAR_region=us-east-1 \
TF_VAR_db_password="$DB_PASSWORD" \
terraform plan -input=false -var-file=ci.tfvars

6. Pass required inputs to child modules in the calling block:

module "network" {
  source = "./modules/network"
  region = var.region   # the module declared this as required
  cidr   = "10.0.0.0/16"
}

7. Add a default for genuinely optional values so they stop being required:

variable "region" {
  type    = string
  default = "us-east-1"
}

Prevention and Best Practices

  • Give safe, environment-agnostic values a default; reserve no-default (required) for things that must be chosen per environment or are secrets.
  • Standardise on *.auto.tfvars per environment so the right file loads without remembering -var-file.
  • Never default secrets in code — pass them through TF_VAR_* from a secrets manager or CI secret store.
  • Keep -input=false in all automation so a missing value fails fast instead of blocking on a prompt that never gets answered.
  • Document required variables in each module’s README, and add description to every variable block.
  • Precedence to remember (lowest to highest): environment TF_VAR_*, terraform.tfvars, *.auto.tfvars (alphabetical), then -var-file and -var on the command line. Later sources win.
  • Invalid value for input variable — the value was supplied but failed a validation block or type constraint.
  • Variables not allowed — using var. in a context Terraform evaluates too early (like a backend block).
  • Reference to undeclared input variable — referencing var.x with no matching variable block.
  • No value for required variable in a module — same error but raised by a child module whose required input the caller omitted.

Frequently Asked Questions

Why does my terraform.tfvars not get picked up? It only auto-loads from the directory Terraform runs in, and the filename must be exactly terraform.tfvars or end in .auto.tfvars. A file named prod.tfvars requires an explicit -var-file=prod.tfvars.

How do I pass a secret without putting it in a file or shell history? Export it as TF_VAR_<name> from your secrets manager in the same command, for example TF_VAR_db_password="$(vault kv get -field=password ...)" terraform plan. Mark the variable sensitive = true so it is redacted from output.

My pipeline hangs instead of erroring. Why? Without -input=false, Terraform tries to prompt for the missing variable. In CI there is no TTY to answer, so the job appears to hang until it times out. Always pass -input=false in automation.

What is the precedence when a variable is set in several places? Command-line -var and -var-file win over *.auto.tfvars, which win over terraform.tfvars, which wins over TF_VAR_* environment variables. The last -var on the line takes final precedence.

Should I just add a default to every variable to avoid this error? No. A default makes the variable optional, which can mask the fact that an environment-specific or secret value was never supplied. Keep those required and supply them through tfvars or TF_VAR_*.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.