This error occurs when an output block is placed in an invalid location within your Terraform configuration. Output blocks must be defined at the root level of your Terraform files, not nested inside resource, data, module, or other configuration blocks.
Terraform enforces strict syntax rules about where output blocks can appear in your configuration. An output block declares a value that Terraform will expose after applying your infrastructure. These blocks must exist at the root level of your .tf files—the same level where you write resource, data, and variable blocks. When the parser encounters an output block nested inside another block (like inside a resource definition), it rejects it as a syntax error because outputs are top-level constructs in HCL (Terraform's configuration language).
Terraform's error message includes the line number where the output block appears. Open that .tf file and locate the output block:
# Example of incorrect nesting (WRONG)
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
output "instance_id" { # ERROR: output inside resource
value = self.id
}
}In this example, the output block starts on the line with the error.
Cut the output block and paste it at the root level of your Terraform file (same indentation level as resource, data, and variable blocks):
# Correct placement
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
}
output "instance_id" { # Correct: at root level
value = aws_instance.web.id
}The output block should have zero indentation (or consistent with your other root-level blocks).
If you have a resource or block that should have closed earlier, verify all closing braces are in place:
# WRONG: Missing closing brace for resource
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
# Missing } here
output "instance_id" { # Error: parser thinks this is inside resource
value = aws_instance.web.id
}
}
# CORRECT: All braces matched
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
} # Closing brace for resource
output "instance_id" {
value = aws_instance.web.id
}Run Terraform's validation and formatting tools to catch and fix syntax issues:
# Validate syntax
terraform validate
# Auto-format your .tf files (fixes most indentation issues)
terraform fmt -recursiveterraform fmt will reformat your files to correct indentation and structure. This often automatically fixes output placement issues.
Use a code editor with HCL syntax support to visualize block structure:
- Visual Studio Code with HashiCorp Terraform extension
- Terraform extension shows brace matching and nesting
- Enable "bracket pair colorization" to see matching braces
- Use the outline/symbols panel to see all root-level blocks
This helps identify if output blocks are accidentally indented or inside other blocks.
Terraform's HCL parser is strict about block location because outputs have special meaning in the execution model. During the planning phase, Terraform determines which outputs exist and their values. Outputs must be at the module level (root or inside a module definition) to be properly recognized by Terraform's execution engine. This is different from some configuration tools that allow outputs anywhere—Terraform enforces this because outputs are part of the module's public API. In modules, outputs should be in the module's .tf files at the root level of that module directory. If you're writing a module with outputs, ensure all output blocks in the module are at the root of the module directory, not nested inside resources.
Error: Error rendering template: template not found
How to fix "template not found" error in Terraform
Error: Error generating private key
How to fix 'Error generating private key' in Terraform
Error creating Kubernetes Service: field is immutable
How to fix "field is immutable" errors in Terraform
Error: Error creating local file: open: permission denied
How to fix "Error creating local file: permission denied" in Terraform
Error: line endings have changed from CRLF to LF
Line endings have changed from CRLF to LF in Terraform