How to Fix Terraform 'Invalid count argument' Error When Boolean Variable is Null
Threat/Impact Level: HIGH | Exploitability/Downtime Risk: HIGH | Time to Fix: 5 mins
TL;DR
- What broke:
var.enabledisnullat plan time; Terraform cannot evaluatenull ? 1 : 0becausenullis not a valid boolean — the ternary operator does not coercenulltofalse. - How to fix it: Add
default = falseto the variable definition or guard the expression withcoalesce(var.enabled, false) ? 1 : 0. - Use our Client-Side Sandbox below to auto-refactor this — paste your
.tfblock and get corrected HCL instantly without leaking your config.
The Incident (What Does the Error Mean?)
Raw error output:
Error: Invalid count argument
on main.tf line 12, in resource "aws_instance" "this":
12: count = var.enabled ? 1 : 0
The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.
── OR ──
Error: Invalid count argument
The given "count" argument value is null; an integer is required.
Immediate consequence: terraform plan aborts entirely. No diff is generated. If this is in a CI/CD pipeline, the entire apply job fails and no downstream resources are provisioned or destroyed. In a module, every caller of that module is broken simultaneously.
The Attack Vector / Blast Radius
This is a graph evaluation failure, not a runtime error. Terraform builds its dependency graph during the plan phase. The count meta-argument must resolve to a known integer before graph construction completes. When var.enabled is null:
- The ternary
null ? 1 : 0cannot short-circuit — Terraform's type system treatsnullas a distinct type, not asfalse. - The HCL evaluator throws before any resource diff is computed.
- Blast radius in a monorepo: If this variable is passed through a root module into 3–4 child modules, every single module call fails. A single misconfigured
tfvarsfile or a missing environment variable in your pipeline can take down the entireterraform applyrun across all environments. - Blast radius in Terragrunt stacks: Dependent
run_all applychains halt at the first affected module, leaving your infrastructure in a partial state — some resources created, others not.
This is especially dangerous in auto-apply pipelines (Atlantis, Terraform Cloud) where a null variable passed from a dynamic source (e.g., an SSM parameter, a data source, or a workspace variable not yet set) silently breaks production deployments.
How to Fix It (The Solution)
Root Cause in One Line
HCL's ternary operator condition ? true_val : false_val requires condition to be of type bool. null is type null, not bool. Terraform does not implicitly cast.
Basic Fix — Add a Default to the Variable
This is the correct fix 90% of the time. If the variable has no default, any caller that omits it passes null.
variable "enabled" {
- type = bool
+ type = bool
+ default = false
}
With default = false, omitting var.enabled in a tfvars file or module call no longer produces null — it resolves to false, and false ? 1 : 0 evaluates cleanly to 0.
Enterprise Best Practice — Defensive Null Guard at the count Expression
When you cannot change the variable definition (e.g., it lives in a shared module owned by another team, or null is a semantically valid sentinel value meaning "inherit from parent"), guard the expression at the call site.
resource "aws_instance" "this" {
- count = var.enabled ? 1 : 0
+ count = coalesce(var.enabled, false) ? 1 : 0
ami = var.ami_id
instance_type = var.instance_type
}
coalesce(var.enabled, false) returns the first non-null value — so null becomes false, true stays true, false stays false. The downstream ternary then always receives a concrete bool.
Alternative using try() (useful when the entire variable block may be undefined in older Terraform versions):
- count = var.enabled ? 1 : 0
+ count = try(var.enabled, false) ? 1 : 0
Alternative using explicit null check (most readable for code reviewers):
- count = var.enabled ? 1 : 0
+ count = var.enabled != null && var.enabled ? 1 : 0
💡 Tired of pasting proprietary configs into ChatGPT? Generic AI tools log your company's ARNs, DB strings, and private keys. StackEngine is a zero-backend, pure Client-Side WASM utility. Drop your failing config into the sandbox above. We redact your secrets locally in the browser and auto-generate the refactored code using your own API key.
Prevention in CI/CD
1. Enforce Variable Defaults with tflint
Add the tflint-ruleset-terraform rule terraform_required_providers and enable terraform_typed_variables:
# .tflint.hcl
plugin "terraform" {
enabled = true
version = "0.5.0"
source = "github.com/terraform-linters/tflint-ruleset-terraform"
}
rule "terraform_typed_variables" {
enabled = true
}
This flags any bool variable without a default as a warning in your PR pipeline.
2. Checkov Policy — Block Null-Unsafe Count Patterns
# .checkov.yaml
checks:
- id: CKV_TF_NULL_COUNT
name: "Ensure count expressions guard against null booleans"
files:
- "**/*.tf"
Use a custom Checkov check or OPA/Conftest policy to scan for the pattern count = var\.[a-z_]+ \? without a preceding coalesce or try.
3. OPA/Conftest Policy (Rego)
# policies/no_null_count.rego
package terraform
deny[msg] {
resource := input.resource[_][_][_]
count_val := resource.count
# Flag raw ternary on a variable reference without null guard
contains(count_val, "var.")
not contains(count_val, "coalesce")
not contains(count_val, "try")
not contains(count_val, "!= null")
msg := sprintf("Resource count expression '%v' is not null-safe. Wrap with coalesce() or try().", [count_val])
}
4. terraform validate in Every PR
# .github/workflows/tf-validate.yml
- name: Terraform Validate
run: |
terraform init -backend=false
terraform validate
terraform validate catches type mismatches before plan if the variable type is declared as bool and no default is set — it will warn on missing required variables. Pair with -var='enabled=false' as a safe sentinel for validation runs.
5. Workspace / Pipeline Variable Hygiene
In Terraform Cloud / Atlantis, always set a workspace-level default for boolean feature flags. Never rely on the absence of a variable to mean false — Terraform's type system does not share that assumption.