How to fix Error: Null value found in list in Terraform

TerraformINTERMEDIATEMEDIUMUpdated Dec 30, 2025· 139 views

Terraform rejects null values in lists because they create ambiguity in configuration. This error typically occurs with conditional expressions or data source outputs. Use Terraform's built-in functions like compact() or filtering expressions to remove nulls before passing them to list arguments.

Quick fix

Fixes Error: Null value found in list

# Instead of this (may contain nulls):
variable "tags" {
  default = [var.optional_tag, "production"]
}

# Use this:
locals {
  tags = compact([var.optional_tag, "production"])
}

resource "aws_instance" "example" {
  tags = local.tags
}
  1. Use compact() to remove null and empty values
  2. Filter with a for expression to exclude nulls
  3. Use coalesce() to provide default values instead of null
  4. Convert optional data source references to lists safely
terraform — error
# Instead of this (may contain nulls):
variable "tags" {
default = [var.optional_tag, "production"]
}
# Use this:
locals {
tags = compact([var.optional_tag, "production"])
}
resource "aws_instance" "example" {
tags = local.tags
}
Error: Null value found in list

What this error means

In Terraform HCL, the null value represents "absence or omission." While null is valid for individual arguments (where Terraform omits the argument and uses defaults), lists and other collection types cannot contain null elements. When Terraform encounters a null value inside a list—either from a conditional expression, data source output, or variable—it fails validation with this error. This strict validation prevents ambiguous configurations that could lead to unexpected infrastructure state. The error typically manifests during terraform plan when Terraform evaluates your configuration and discovers null values nested within list structures.

Typical symptoms

  • terraform plan fails with 'Null value found in list' message
  • Error occurs when using conditional expressions (? :) in lists
  • Data source outputs with null values cause failure in list contexts
  • Splat expressions (*) or dynamic blocks return null that gets placed in lists
  • Module outputs returning null values added to lists trigger the error

Common causes

  1. Conditional expression returning null inside a list (e.g., [var.optional, "value2"] where var.optional is null)
  2. Data source returning null values that are concatenated or merged into lists
  3. Optional variable with null default used directly in list without filtering
  4. For-loop expressions not filtering out null values before creating a list
  5. Module outputs or local values that resolve to null placed in list arguments

How to fix "Error: Null value found in list"

1Use compact() to remove null and empty values

The compact() function removes null and empty string values from a list of strings. This is the simplest fix for most cases.

hcl
# Instead of this (may contain nulls):
variable "tags" {
  default = [var.optional_tag, "production"]
}

# Use this:
locals {
  tags = compact([var.optional_tag, "production"])
}

resource "aws_instance" "example" {
  tags = local.tags
}

The compact() function only works with string lists. For other types, use the filtering approach below.

2Filter with a for expression to exclude nulls

For non-string lists or more control, use a for expression with a conditional filter.

hcl
# For any list type, filter out nulls:
locals {
  security_group_ids = [for sg_id in var.optional_security_groups : sg_id if sg_id != null]
}

resource "aws_instance" "example" {
  vpc_security_group_ids = local.security_group_ids
}

# Or filter directly in the resource argument:
resource "aws_instance" "example" {
  vpc_security_group_ids = [for sg_id in var.sg_list : sg_id if sg_id != null]
}

This approach works with any data type and gives you complete control over filtering logic.

3Use coalesce() to provide default values instead of null

Instead of allowing null values, use coalesce() to substitute a default value when a variable is null.

hcl
# Instead of:
variable "optional_protocol" {
  default = null
}

resource "aws_security_group_rule" "example" {
  from_port   = 443
  to_port     = 443
  protocol    = var.optional_protocol  # This could be null!
}

# Use coalesce to provide a default:
resource "aws_security_group_rule" "example" {
  from_port   = 443
  to_port     = 443
  protocol    = coalesce(var.optional_protocol, "tcp")
}

This ensures a valid value is always present, eliminating null entirely.

4Convert optional data source references to lists safely

When a data source lookup might return null, use try() to catch the error and provide an empty list or fallback.

hcl
# Instead of:
data "aws_ami" "ubuntu" {
  filter {
    name   = "name"
    values = [var.optional_ami_name]  # Might be null!
  }
}

# Use try() with a fallback:
locals {
  # Returns [] if the lookup fails or returns null
  ami_list = try([data.aws_ami.ubuntu.id], [])
}

resource "aws_instance" "example" {
  ami = try(data.aws_ami.ubuntu.id, var.fallback_ami_id)
}

The try() function catches errors and exceptions, allowing you to provide safe fallback values.

5Check optional variables before using in lists

If a variable is genuinely optional, make it clear in your variable definition and handle it explicitly.

hcl
variable "additional_security_groups" {
  type        = list(string)
  default     = []  # Use empty list as default, not null
  description = "Additional security groups. Leave empty to skip."
}

variable "optional_tag" {
  type    = string
  default = ""  # Use empty string instead of null
  description = "Optional tag value. Leave empty to omit."
}

# Then filter out empty strings if needed:
locals {
  tags = [for tag in [var.optional_tag, "required"] : tag if tag != ""]
}

This makes it explicit that these values are optional and avoids null entirely.

Advanced notes

Advanced handling: Terraform 1.5+ improved the compact() function to handle non-string list types. For older versions, the for expression filtering approach is more reliable. When dealing with optional module inputs, consider using dynamic blocks instead of lists—they handle null gracefully:

hcl
resource "aws_instance" "example" {
  ami = var.ami_id

  dynamic "root_block_device" {
    for_each = var.root_block_config != null ? [var.root_block_config] : []
    content {
      volume_size = root_block_device.value.size
    }
  }
}

This pattern avoids lists altogether for optional configurations.

Frequently asked questions

What does "Error: Null value found in list" mean?
" While null is valid for individual arguments (where Terraform omits the argument and uses defaults), lists and other collection types cannot contain null elements. When Terraform encounters a null value inside a list—either from a conditional expression, data source output, or variable—it fails validation with this error. This strict validation prevents ambiguous configurations that could lead to unexpected infrastructure state.
How do I fix "Error: Null value found in list"?
Terraform rejects null values in lists because they create ambiguity in configuration. This error typically occurs with conditional expressions or data source outputs. Use Terraform's built-in functions like compact() or filtering expressions to remove nulls before passing them to list arguments.
What causes "Error: Null value found in list"?
Conditional expression returning null inside a list (e.g., [var.optional, "value2"] where var.optional is null) Data source returning null values that are concatenated or merged into lists Optional variable with null default used directly in list without filtering
Is the "Error: Null value found in list" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading