Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for OpenTofu By James Joyner IV · · 8 min read Last reviewed Jul 2026

OpenTofu Error: 'Duplicate variable declaration' Two variable Blocks Same Name

Quick answer

Fix OpenTofu's 'Duplicate variable declaration' error: find and remove the second variable block with the same name, often left behind after merges or refactors.

  • #opentofu
  • #terraform
  • #iac
  • #troubleshooting
  • #errors
Free toolkit

Stuck on this OpenTofu error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Exact Error Message


│ Error: Duplicate variable declaration

│   on variables.tf line 21:
│   21: variable "region" {

│ A variable named "region" was already declared at variables.tf:3,1-19.
│ Variable names must be unique within a module.

The message names the duplicated variable and points at both the second declaration and the location of the first one it conflicts with.

What It Means

Within a single module, every variable block must have a unique name. OpenTofu loads all .tf files in a module directory and treats them as one combined configuration, so two variable "region" {} blocks — even in different files — collide. When it finds a second declaration of the same name, it stops with Duplicate variable declaration and shows you both locations.

This is a configuration authoring error, not a state or provider problem. It commonly appears after a merge conflict is resolved sloppily, after copy-pasting a block, or after splitting variables across files without noticing an overlap. The same rule applies to output, resource, module, and locals names.

Common Causes

  • The same variable block was copy-pasted into two files (for example variables.tf and main.tf).
  • A merge or rebase kept both sides of a conflict, leaving two identical declarations.
  • Variables were split into multiple files and one name was duplicated by accident.
  • A generated file (from a template or scaffolding tool) redeclares a variable that already exists.
  • A leftover variables.tf.bak or similar file with a .tf extension is being loaded alongside the real one.

Diagnostic Commands

Let OpenTofu report both conflicting locations:

tofu validate

Find every declaration of the duplicated name across the module:

grep -rn 'variable "region"' .

List all .tf files OpenTofu will load, in case a backup file sneaked in:

ls -1 *.tf

Count declarations per variable name to spot any other duplicates:

grep -rhoE 'variable "[a-zA-Z0-9_]+"' *.tf | sort | uniq -c | sort -rn

Step-by-Step Resolution

  1. Run tofu validate. The error lists both the second declaration and the already declared at location of the first.

  2. Search the whole module directory for the name so you see every copy:

grep -rn 'variable "region"' .
  1. Decide which declaration is canonical. Keep the one with the correct type, description, and default, and delete the redundant block entirely:
# variables.tf — keep this one
variable "region" {
  type        = string
  description = "AWS region to deploy into."
  default     = "us-east-1"
}
  1. Remove the duplicate from the other file. Do not comment it out — a commented block is fine, but leaving a second live variable "region" block anywhere will re-trigger the error.

  2. If the duplicate came from a merge conflict, make sure no conflict markers (<<<<<<<, =======, >>>>>>>) remain and that only one version survived.

  3. Check for stray files with a .tf extension that OpenTofu is loading unintentionally:

ls -1 *.tf
# rename or remove variables.tf.bak, old-variables.tf, etc.
  1. Validate again to confirm the module now parses cleanly:
tofu validate

Prevention

  • Declare each variable exactly once and keep all declarations in a single variables.tf per module so duplicates are obvious.
  • Never store backup copies with a .tf extension in the module directory; OpenTofu loads every .tf file. Use .tf.bak outside the directory or a separate folder.
  • Resolve merge conflicts carefully and run tofu validate immediately afterward.
  • Add tofu validate to CI so duplicate declarations fail before they reach anyone else’s checkout.
  • Periodically audit declarations with grep ... | uniq -c to catch overlaps early. The prompt library has prompts that consolidate scattered variable blocks into one clean file.
  • Duplicate output definition — the same uniqueness rule applied to two output blocks.
  • Duplicate resource "type" "name" configuration — two resource blocks sharing type and name.
  • Duplicate required providers configuration — more than one required_providers block in a module.
  • Reference to undeclared input variable — the opposite problem: a reference with no declaration at all.

Frequently Asked Questions

Why does a duplicate in a different file still fail? OpenTofu merges all .tf files in a module directory into one configuration before evaluating it, so names must be unique across the whole directory, not just per file.

Can two modules both declare a variable named “region”? Yes. The uniqueness rule is per module. Two separate modules (different directories) may each declare their own region variable without conflict.

Is a leftover backup file really loaded? Any file ending in .tf (or .tf.json) in the module directory is loaded. A file like variables_old.tf will be parsed and can cause a duplicate. Move or rename it.

Does commenting out the second block fix it? Yes, but deleting it is cleaner. A fully commented-out block is not parsed as a declaration, so only the remaining live block counts.

Where can I find more OpenTofu fixes? Browse the OpenTofu guides for the complete set of error walkthroughs.

Free download · 368-page PDF

Fixed it? Get 500 OpenTofu & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.