Skip to main content
DevOps Insightsguides & answers

Terraform · troubleshooting

Error: Unsupported attribute

A reference asks for an attribute that the value it points at does not have. Usually a module output that was never declared, a misspelt attribute, a field read from a whole list instead of one element, or an output missing from remote state.

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

Before you start

  • terraform init run in the directory.

Run this first

step 1 of 1
terraform console

Look for Where the shape stops matching the reference

Evaluate the reference piece by piece to see the real shape of each value.

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

What does the reference start with?

Cause space

4 of 4 still possible

  • The module has no output with that nameCommon
  • The attribute is misspelt, or the provider renamed itCommon
  • A field read from a whole list, or a count resource without an indexCommon
  • The remote state does not have that outputOccasional

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

    terraform console

    Evaluate the reference piece by piece to see the real shape of each value.

    Look for Where the shape stops matching the reference

Every cause, and how to fix it

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

The module has no output with that name

Common

Resources inside a module are private. module.NAME.X works only if the module has output "X".

Confirm

grep -rn 'output "' path/to/module/*.tf

No output with the name you referenced

Fix

  • Add an output block to the module that returns the value, then reference module.NAME.OUTPUT.
output "subnet_id" {
  value = aws_subnet.this.id
}

In the module. Reproduced with a local module on Terraform 1.14.0.

The attribute is misspelt, or the provider renamed it

Common

A typo usually gets a Did you mean suggestion. After a provider major upgrade, an attribute can be renamed or removed; that case was not reproduced here.

Confirm

terraform validate

A Did you mean line

Fix

  • Use the suggested name, or the attribute list on the resource's documentation page for the provider version you run.

A field read from a whole list, or a count resource without an index

Common

A list of objects has no fields itself; each element does. A resource with count or for_each is a collection of instances.

Confirm

terraform console

Type the expression without the last name: a list or tuple, not an object

Fix

  • One element: var.cfg.subnets[0].name or aws_instance.web[0].id.
  • All elements: var.cfg.subnets[*].name or aws_instance.web[*].id.
  • for_each resources are maps: [for k, v in aws_instance.web : v.id], or aws_instance.web["key"].id.

The remote state does not have that output

Occasional

data.terraform_remote_state.X.outputs only contains outputs the other configuration declared and applied. validate cannot know them, so this fails at plan.

Confirm

terraform plan

outputs is object with N attributes, listing the names it does have

Fix

  • Add the output to the other configuration and apply it there first.
  • If the output is genuinely optional, read it with try(data.terraform_remote_state.X.outputs.NAME, null).

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

Every value in Terraform has a shape. A module exposes only its outputs, a resource only its attributes, and a list has elements rather than fields. Asking for a name the shape does not contain stops Terraform, and the message usually prints the shape it actually found.

Words used on this page

Module output
The only values a module exposes, declared with output blocks inside it.
Splat [*]
list[*].name takes name from every element of a list and returns a list.
Resource instance key
The [0] or ["name"] that picks one copy of a resource created with count or for_each.
What is actually happening

Reproduced on Terraform 1.14.0. Reading an output a module does not declare printed module.net is a object and This object does not have an attribute named "subnet_id". A misspelt resource attribute printed This object has no argument, nested block, or exported attribute named "inputs". Did you mean "input"?

Reading a field straight off a list printed Can't access attributes on a list of objects, asking whether you meant one element or all of them. A resource with count, referenced without an index, gives a sibling error, Missing resource instance key.

A terraform_remote_state reference to an output the other configuration does not have passed terraform validate and failed only at plan, where the message listed the outputs the state really has.

How to tell this is your problem
WhereWhat you see
terraform validate or planError: Unsupported attribute ... This object does not have an attribute named "NAME".
A listCan't access attributes on a list of objects. Did you mean to access attribute "NAME" for a specific element of the list, or across all elements of the list?
count or for_each resourceError: Missing resource instance key ... its attributes must be accessed on specific instances.

How to know it is actually fixed

  • terraform validate and terraform plan run without the error.

Stopping it happening again

  • Give modules explicit outputs for everything callers need.
  • Pin provider versions and read upgrade guides before major upgrades.

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