The Error
โ Error: Invalid value for input variable
โ
โ on terraform.tfvars line 3:
โ 3: instance_count = "2"
โ
โ The given value is not suitable for var.instance_count: a number is required.
This blows up during terraform plan or terraform apply. Terraform read your .tfvars file, found the variable, and then rejected the value because its type doesn't match the variable declaration. The plan never starts.
Root Cause
Terraform's type system doesn't coerce silently. Declare a variable as type = number and pass a quoted string like "2"? Rejected. No automatic conversion happens โ Terraform expects the exact type. This applies to bool, list, map, and object types too.
The mismatch usually comes from one of these situations:
- A number or bool wrapped in quotes in the
.tfvarsfile - A
listvariable passed as a plain comma-separated string - An
objectvariable missing one or more required attributes - The variable type changed in
variables.tfbut the.tfvarsfile was never updated to match
Fix 1: Remove Quotes from Number and Bool Values
Ninety percent of the time, this is the culprit. HCL has a straightforward rule: strings get quotes, everything else doesn't.
Wrong:
# terraform.tfvars
instance_count = "2" # string, not a number
enable_logging = "true" # string, not a bool
Correct:
# terraform.tfvars
instance_count = 2 # number โ no quotes
enable_logging = true # bool โ no quotes
Numbers, booleans, lists, and maps all go unquoted. Only string values need the double quotes.
Fix 2: Fix List and Set Variables
Passing a list(string) as a comma-separated string is another common trap. Terraform won't split it for you.
Variable declaration:
# variables.tf
variable "availability_zones" {
type = list(string)
}
Wrong:
# terraform.tfvars
availability_zones = "us-east-1a,us-east-1b"
Correct:
# terraform.tfvars
availability_zones = ["us-east-1a", "us-east-1b"]
Fix 3: Fix Map and Object Variables
HCL maps use { key = value } syntax โ not JSON-style colons. If you copy-paste from a JSON config, the colons will break it.
Variable declaration:
# variables.tf
variable "tags" {
type = map(string)
}
variable "db_config" {
type = object({
engine = string
version = string
port = number
})
}
Correct tfvars syntax:
# terraform.tfvars
tags = {
Environment = "production"
Team = "platform"
}
db_config = {
engine = "postgres"
version = "14.5"
port = 5432
}
Watch port โ it's typed as number, so 5432 has no quotes. Writing "5432" triggers the same error you're trying to fix.
Fix 4: Passing Variables via CLI Flag
Using -var on the command line? Type handling works differently there. Terraform receives the value as a string and converts it based on the declared type โ which works fine for simple scalars, but falls apart with lists, maps, and objects.
For anything beyond a basic number or bool, use a .tfvars file:
# Fragile for complex types:
terraform plan -var='instance_count=2'
# More reliable:
terraform plan -var-file="production.tfvars"
Simple number and bool variables generally survive -var fine. The headaches start with list, map, and object.
Fix 5: Check for Type Drift Between Modules
Updated a module recently and changed a variable's type? Your root module's .tfvars might still be using the old format. This one is subtle โ the error message points to the tfvars file, not the module where the type actually changed.
# Inspect what type Terraform actually expects:
terraform console
> var.instance_count
Or go straight to the source:
grep -A5 'variable "instance_count"' variables.tf
Quick Diagnostic: Validate Without Applying
Run terraform validate before touching plan:
terraform validate
It won't load your tfvars, so it misses value-level mismatches. But it catches declaration errors fast. For full validation โ tfvars included โ run plan and pipe the output:
terraform plan -var-file="your.tfvars" 2>&1 | head -30
Verifying the Fix
Once you've corrected the type in your tfvars file, run plan again:
terraform plan
No Invalid value for input variable line means the mismatch is gone. A clean plan looks like this:
Terraform will perform the following actions:
# aws_instance.web will be created
+ resource "aws_instance" "web" {
...
}
Plan: 1 to add, 0 to change, 0 to destroy.
From there you're dealing with infrastructure logic, not type errors.
Prevention
Three habits that make this class of error rare:
- Declare types explicitly in
variables.tf. Without a type constraint, Terraform accepts anything โ and problems surface at runtime instead of plan time, where they're harder to trace. - Add
validationblocks for stricter checks. They produce clear, human-readable messages rather than the raw type error you're looking at now. - Keep a
terraform.tfvars.examplein git with correct types shown. Anyone updating a variable then has a reference for what format to use. - Run
terraform planin CI against your actual tfvars files. Type drift gets caught before it reaches production.
# variables.tf โ explicit type + validation
variable "instance_count" {
type = number
description = "Number of EC2 instances to create"
default = 1
validation {
condition = var.instance_count >= 1 && var.instance_count <= 20
error_message = "instance_count must be between 1 and 20."
}
}
With that validation block in place, a bad value gives you "instance_count must be between 1 and 20" โ not the cryptic type error you'd otherwise spend 10 minutes googling at 2am.

