TerraformPilot

DevOps

Fix Terraform Error - Error Creating Route - RouteAlreadyExists

How to fix RouteAlreadyExists errors when managing VPC route tables in Terraform. Handle duplicate routes, inline vs separate resources, and default route...

LLuca Berton2 min read

Quick Answer

#

A route with that destination CIDR already exists in the route table. Either import the existing route, remove the duplicate definition, or switch from inline routes to separate aws_route resources (or vice versa). Never mix inline and separate routes for the same route table.

The Error

#
Error creating Route: RouteAlreadyExists: The route identified by 0.0.0.0/0 already exists

Or with specific CIDRs:

Error creating Route: RouteAlreadyExists: The route identified by 10.0.0.0/16 already exists

What Causes This

#

1. Route Created Outside Terraform

#

Someone added the route manually in the AWS Console, or another tool created it.

2. Mixing Inline and Separate Route Resources

#
# ❌ WRONG — this creates the same route twice
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"          # Inline route
    gateway_id = aws_internet_gateway.main.id
  }
}
 
resource "aws_route" "internet" {
  route_table_id         = aws_route_table.public.id
  destination_cidr_block = "0.0.0.0/0"  # Separate route — CONFLICT!
  gateway_id             = aws_internet_gateway.main.id
}

3. Duplicate Definitions Across Files

#

The same route defined in two different .tf files.

4. VPC Default Route Conflict

#

AWS creates a local route (e.g., 10.0.0.0/16 → local) automatically — you can't override it.

How to Fix It

#

Solution 1: Import the Existing Route

#
# Format: route_table_id_destination_cidr
terraform import aws_route.internet rtb-0123456789abcdef0_0.0.0.0/0
#
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
  # NO inline routes
}
 
resource "aws_route" "internet" {
  route_table_id         = aws_route_table.public.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.main.id
}
 
resource "aws_route" "nat" {
  route_table_id         = aws_route_table.private.id
  destination_cidr_block = "0.0.0.0/0"
  nat_gateway_id         = aws_nat_gateway.main.id
}

Solution 3: Use Only Inline Routes

#
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
 
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
 
  route {
    cidr_block                = "10.1.0.0/16"
    vpc_peering_connection_id = aws_vpc_peering_connection.peer.id
  }
}

Solution 4: Find and Remove Duplicates

#
# Search for duplicate route definitions
grep -rn 'destination_cidr_block.*0.0.0.0/0' *.tf modules/**/*.tf

Inline vs Separate Routes

#
ApproachProsCons
Inline (route {})Simple, all in one placeManages ALL routes — can't mix
Separate (aws_route)Granular control, modularMore resources to manage

Rule: Pick one approach per route table and stick with it.

Troubleshooting Checklist

#
  1. ✅ Is the route defined both inline and as a separate resource?
  2. ✅ Was the route created manually in AWS Console?
  3. ✅ Is the same CIDR defined in multiple .tf files?
  4. ✅ Are you trying to override the VPC's local route?

Prevention Tips

#
  • Choose inline OR separate routes — never mix per route table
  • Import manually-created routes before adding them to Terraform
  • Use terraform plan to catch conflicts before applying
  • Search for duplicates when adding new routes
#

Conclusion

#

RouteAlreadyExists means the route exists — either outside Terraform or as a duplicate definition. Import it, remove the duplicate, and never mix inline and separate route resources on the same route table.

#Terraform#Troubleshooting#DevOps#Error Fix#Infrastructure as Code

Share this article