What's Actually Happening
You're trying to reference or read an output value from Terraform, but Terraform cannot find it. This could be a root module output that doesn't exist, a module output not defined, or a remote state output that isn't accessible. Output errors block reading infrastructure information and can prevent dependent configurations from working.
The Error You'll See
For root module outputs:
``` Error: Output "vpc_id" not found
The root module does not have an output named "vpc_id"
Error: No outputs defined
The module has no outputs defined. Add outputs to expose values. ```
For module outputs:
``` Error: Module "vpc" has no output "public_subnet_id"
Module outputs: vpc_id, private_subnet_ids Available outputs do not include "public_subnet_id"
Error: Reference to undeclared output
on main.tf line 25: 25: subnet_id = module.vpc.public_subnet_id
Module module.vpc does not have an output named "public_subnet_id". ```
For remote state outputs:
``` Error: Output "database_url" not found in remote state
The remote state does not contain an output named "database_url".
Error: Cannot read outputs from remote state
State does not contain outputs section. ```
Why This Happens
Output not found errors occur due to:
- 1.Output not defined - Missing output block in configuration
- 2.Output name typo - Wrong name when referencing
- 3.Module not applied - Module never ran so outputs don't exist
- 4.State empty - No outputs section in state file
- 5.Remote state inaccessible - Cannot reach remote state backend
- 6.Output sensitive - Sensitive outputs not exposed by default
- 7.Wrong module path - Incorrect module address in reference
- 8.Configuration error - Output value refers to non-existent resource
Step 1: List Available Outputs
Check what outputs actually exist:
```bash # List root module outputs terraform output
# You'll see all defined outputs: # vpc_id = "vpc-12345678" # subnet_ids = [ # "subnet-11111111", # "subnet-22222222", # ]
# List specific output terraform output vpc_id
# List all outputs in JSON format terraform output -json
# Check module outputs terraform output -json | jq '.modules[]' ```
Step 2: Verify Output Definition
Check output is defined in configuration:
```hcl # In outputs.tf or main.tf output "vpc_id" { value = aws_vpc.main.id }
output "subnet_ids" { value = aws_subnet.public[*].id }
output "database_endpoint" { value = aws_db_instance.main.endpoint } ```
If output is missing, add it:
```hcl # Add missing output output "public_subnet_id" { value = aws_subnet.public.id }
# Or for modules, in modules/vpc/outputs.tf output "public_subnet_id" { value = aws_subnet.public.id }
output "vpc_id" { value = aws_vpc.main.id } ```
Step 3: Fix Output Name Typos
Check reference matches actual output name:
```hcl # WRONG - typo in output name resource "aws_instance" "web" { subnet_id = module.vpc.publik_subnet_id # typo: "publik" }
# CORRECT - exact output name resource "aws_instance" "web" { subnet_id = module.vpc.public_subnet_id # matches output definition }
# Check module's outputs # cat modules/vpc/outputs.tf output "public_subnet_id" { # This is the exact name value = aws_subnet.public.id } ```
Verify exact output names:
```bash # Check module outputs definition cat modules/vpc/outputs.tf
# Or check via state after apply terraform state show module.vpc ```
Step 4: Handle Module Outputs
Module must be applied before outputs exist:
```bash # Apply module first terraform apply -target=module.vpc
# Then outputs become available terraform output
# Reference module outputs module.vpc.vpc_id module.vpc.public_subnet_id ```
Module outputs definition:
```hcl # In modules/vpc/outputs.tf output "vpc_id" { description = "The ID of the VPC" value = aws_vpc.main.id }
output "public_subnet_ids" { description = "List of public subnet IDs" value = aws_subnet.public[*].id }
output "private_subnet_ids" { description = "List of private subnet IDs" value = aws_subnet.private[*].id } ```
Reference correctly:
```hcl module "vpc" { source = "./modules/vpc" cidr = "10.0.0.0/16" }
# Reference module outputs resource "aws_instance" "web" { subnet_id = module.vpc.public_subnet_ids[0] vpc_id = module.vpc.vpc_id } ```
Step 5: Handle Remote State Outputs
For cross-state references:
```hcl # Read outputs from remote state data "terraform_remote_state" "networking" { backend = "s3"
config = { bucket = "my-terraform-state" key = "networking/terraform.tfstate" region = "us-east-1" } }
# Reference remote state outputs resource "aws_instance" "web" { subnet_id = data.terraform_remote_state.networking.outputs.public_subnet_id } ```
Verify remote state has outputs:
```bash # Check remote state content aws s3 cp s3://my-terraform-state/networking/terraform.tfstate - | jq '.outputs'
# Or if using local state for testing cat terraform.tfstate | jq '.outputs' ```
Handle missing outputs in remote state:
```bash # If remote state lacks outputs section # The source configuration needs to define and apply outputs
# In the networking configuration: output "public_subnet_id" { value = aws_subnet.public.id }
# Apply to generate outputs terraform apply
# Outputs now available in remote state ```
Step 6: Handle Sensitive Outputs
Sensitive outputs have special handling:
# Sensitive output definition
output "database_password" {
value = aws_db_instance.main.password
sensitive = true
}Accessing sensitive outputs:
```bash # terraform output by default masks sensitive values terraform output database_password # Output: <sensitive>
# Use -raw flag to get actual value terraform output -raw database_password
# Or in JSON with sensitive values terraform output -json | jq '.database_password.value' ```
For module sensitive outputs:
```hcl # Module must mark output as sensitive output "admin_password" { value = random_password.admin.result sensitive = true }
# Reference in root module (value accessible but marked sensitive) module.compute.admin_password ```
Step 7: Fix Output Value Errors
When output references non-existent resource:
```hcl # Error: output references missing resource output "instance_ip" { value = aws_instance.web_server.public_ip }
# If aws_instance.web_server doesn't exist: # Error: Reference to undeclared resource ```
Fix the output definition:
```hcl # Ensure referenced resource exists resource "aws_instance" "web" { ami = var.ami_id instance_type = "t3.micro" }
# Then output can reference it output "instance_ip" { value = aws_instance.web.public_ip }
# Or use conditional for optional resources output "instance_ip" { value = aws_instance.web[count.index].public_ip } ```
Step 8: Debug Output Issues
Enable detailed logging:
```bash export TF_LOG=DEBUG terraform output 2>&1 | grep -i output
# Check state file directly terraform state pull | jq '.outputs' ```
Use terraform console:
```bash terraform console > module.vpc > module.vpc.vpc_id > aws_vpc.main.id
# Test output expressions > aws_subnet.public[*].id ```
Step 9: Handle Complex Output Types
For complex output values:
```hcl # Map output output "instance_ips" { value = { for instance in aws_instance.web : instance.tags["Name"] => instance.public_ip } }
# List output from for_each output "subnet_ids" { value = [for s in aws_subnet.public : s.id] }
# Nested output output "network_info" { value = { vpc_id = aws_vpc.main.id subnet_ids = aws_subnet.public[*].id cidr = aws_vpc.main.cidr_block } } ```
Access complex outputs:
```bash # JSON output for complex types terraform output -json network_info | jq '.vpc_id'
# Or in Terraform console terraform console > terraform.output.network_info.vpc_id ```
Step 10: Handle Output in CI/CD
Extract outputs for automation:
```bash # Get output for script VPC_ID=$(terraform output -raw vpc_id)
# Use in subsequent commands aws ec2 describe-vpcs --vpc-ids $VPC_ID
# Export for other tools export TF_OUTPUT_vpc_id=$(terraform output -raw vpc_id) ```
GitHub Actions example:
```yaml jobs: terraform: steps: - name: Terraform Apply run: terraform apply -auto-approve
- name: Get Outputs
- id: outputs
- run: |
- echo "vpc_id=$(terraform output -raw vpc_id)" >> $GITHUB_OUTPUT
- name: Use Output
- run: |
- echo "VPC ID: ${v steps.outputs.outputs.vpc_id}"
`
Verify the Fix
After fixing output issues:
```bash # Verify output is defined and accessible terraform output vpc_id
# Should return the value: # vpc-12345678
# Check all outputs terraform output
# Verify state has outputs section terraform state pull | jq '.outputs | keys' ```
Test module outputs:
```bash # Apply module terraform apply
# Check module outputs terraform output -json | jq '.modules[0].outputs' ```
Prevention Best Practices
Always define outputs:
```hcl # Create outputs.tf in every module output "vpc_id" { description = "The VPC ID for use by other modules" value = aws_vpc.main.id }
output "subnet_ids" { description = "Subnet IDs for compute resources" value = aws_subnet.public[*].id } ```
Document required outputs:
## Required Outputs
Modules consuming this module expect:
- vpc_id: VPC ID
- subnet_ids: List of subnet IDs
- security_group_id: Security group for instancesUse output validation:
```hcl output "vpc_id" { value = aws_vpc.main.id
precondition { condition = aws_vpc.main.id != "" error_message = "VPC ID must not be empty." } } ```