How to fix Error: Error creating subnet: InvalidSubnet.Range in Terraform

TerraformINTERMEDIATEHIGHUpdated Dec 30, 2025· 166 views

The InvalidSubnet.Range error occurs when your Terraform subnet CIDR block is invalid or doesn't fit within your VPC's IP address space. This typically happens when the subnet CIDR is outside the VPC range, overlaps with existing subnets, or when using secondary CIDR blocks before they're fully associated.

Quick fix

Fixes Error: Error creating subnet: InvalidSubnet.Range

# View your Terraform state or configuration
terraform state show aws_vpc.main
terraform state show aws_subnet.example

# Or check directly in AWS
aws ec2 describe-vpcs --query 'Vpcs[*].[VpcId,CidrBlock]' --output table
  1. Verify your VPC CIDR block
  2. Check for overlapping subnets
  3. Use cidrsubnet() for safe subnet calculation
  4. Fix secondary VPC CIDR timing issues
terraform — error
# View your Terraform state or configuration
terraform state show aws_vpc.main
terraform state show aws_subnet.example
# Or check directly in AWS
aws ec2 describe-vpcs --query 'Vpcs[*].[VpcId,CidrBlock]' --output table
Error: Error creating subnet: InvalidSubnet.Range

What this error means

When creating an AWS subnet with Terraform, the subnet's CIDR block must be a valid subset of the VPC's CIDR block. The InvalidSubnet.Range error indicates that the CIDR block you're trying to assign to your subnet violates AWS subnet requirements. This error commonly occurs when: - The subnet CIDR is completely outside the VPC's address range (e.g., VPC is 10.0.0.0/16 but subnet is 172.16.0.0/24) - The subnet size is too large (subnets must be at least /28) or uses invalid boundaries - Multiple subnets overlap with each other - Using secondary VPC CIDR blocks before they're fully provisioned - IPv6 CIDR block issues when enabling IPv6 on subnets AWS maintains strict validation to prevent IP address exhaustion and routing conflicts within your VPC.

Typical symptoms

  • Terraform apply fails with 'Error creating subnet: InvalidSubnet.Range'
  • Error message specifies 'The CIDR X.X.X.X/YY is invalid'
  • Subnet creation fails even though the CIDR appears valid
  • Works on second terraform apply (timing issue with secondary CIDR blocks)
  • IPv6 subnet creation fails with 'The IPv6 CIDR is invalid'
  • Multiple subnet resources fail in the same apply
  • Error occurs when changing VPC CIDR block

Common causes

  1. Subnet CIDR block is outside the VPC's CIDR range (most common)
  2. Subnet CIDR size violates AWS limits (must be between /16 and /28)
  3. Subnet CIDR overlaps with an existing subnet in the VPC
  4. Using secondary VPC CIDR before the association is ready
  5. Invalid CIDR block syntax or calculation error with cidrsubnets() function
  6. IPv6 CIDR block configuration issues on the VPC or subnet
  7. Attempting to reuse a CIDR block that's already in use
  8. Mixing and matching CIDR calculations without verifying output

How to fix "Error: Error creating subnet: InvalidSubnet.Range"

1Verify your VPC CIDR block

First, confirm the CIDR range of your VPC and the subnet you're trying to create:

bash
# View your Terraform state or configuration
terraform state show aws_vpc.main
terraform state show aws_subnet.example

# Or check directly in AWS
aws ec2 describe-vpcs --query 'Vpcs[*].[VpcId,CidrBlock]' --output table

In your Terraform code, verify the VPC CIDR block:

hcl
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"  # Your VPC range
}

resource "aws_subnet" "example" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"  # Must be within 10.0.0.0/16
}

The subnet CIDR block must be entirely within the VPC's range. Common private IP ranges are:
- 10.0.0.0/8 (10.0.0.0 to 10.255.255.255)
- 172.16.0.0/12 (172.16.0.0 to 172.31.255.255)
- 192.168.0.0/16 (192.168.0.0 to 192.168.255.255)

2Check for overlapping subnets

List all subnets in your VPC to identify overlaps:

bash
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-xxxxx" \
  --query 'Subnets[*].[SubnetId,CidrBlock,AvailabilityZone]' --output table

Or in Terraform, check your state file:

bash
terraform state list | grep aws_subnet
terraform state show aws_subnet.subnet1
terraform state show aws_subnet.subnet2

Subnets cannot overlap. For example, if you have:
- Subnet A: 10.0.1.0/24 (10.0.1.0 to 10.0.1.255)
- Subnet B: 10.0.1.128/25 (10.0.1.128 to 10.0.1.255) ← OVERLAPS!

You need to use non-overlapping ranges:
- Subnet A: 10.0.1.0/24
- Subnet B: 10.0.2.0/24

3Use cidrsubnet() for safe subnet calculation

Use Terraform's cidrsubnet() function to automatically calculate non-overlapping subnets:

hcl
# Define VPC with /16 CIDR block
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

# Create subnets safely using cidrsubnet
resource "aws_subnet" "public_1" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(aws_vpc.main.cidr_block, 2, 0)  # 10.0.0.0/18
  availability_zone = "us-east-1a"
}

resource "aws_subnet" "public_2" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(aws_vpc.main.cidr_block, 2, 1)  # 10.0.64.0/18
  availability_zone = "us-east-1b"
}

resource "aws_subnet" "private_1" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(aws_vpc.main.cidr_block, 2, 2)  # 10.0.128.0/18
  availability_zone = "us-east-1a"
}

The cidrsubnet() function signature: cidrsubnet(prefix, newbits, netnum)
- prefix: VPC CIDR block (e.g., "10.0.0.0/16")
- newbits: Number of bits to add to subnet mask (e.g., 2 = /18)
- netnum: Subnet number (0, 1, 2...)

This automatically prevents overlaps!

Important: If you get "not enough remaining address space", adjust newbits downward:

hcl
# If this fails with too many subnets:
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)  # /24

# Try a larger block size:
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 4, count.index)  # /20
4Fix secondary VPC CIDR timing issues

If you're using secondary CIDR blocks, Terraform may try to create subnets before the CIDR association is complete.

Problem scenario:

hcl
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_vpc_ipv4_cidr_block_association" "secondary" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.2.0.0/16"
}

# Error: Secondary CIDR not ready yet!
resource "aws_subnet" "secondary_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.2.0.0/24"
}

Solution: Add explicit dependency

hcl
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_vpc_ipv4_cidr_block_association" "secondary" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.2.0.0/16"
}

# Explicitly depend on secondary CIDR association
resource "aws_subnet" "secondary_subnet" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.2.0.0/24"
  depends_on        = [aws_vpc_ipv4_cidr_block_association.secondary]
}

If you still get errors after adding depends_on, run terraform twice:

bash
# First apply: Creates VPC and associates secondary CIDR
terraform apply

# Second apply: Creates subnets once CIDR is fully ready
terraform apply
5Validate CIDR blocks before applying

Use terraform plan to validate before applying:

bash
terraform plan -out=tfplan

Review the plan output for:
- Subnet CIDR blocks make sense
- No obvious overlaps (review all subnets in the plan)
- Correct VPC associations

You can also manually verify CIDR blocks with an online CIDR calculator or test in your AWS console first:

bash
# Use AWS CLI to validate
aws ec2 describe-vpcs --vpc-ids vpc-12345678 \
  --query 'Vpcs[0].[CidrBlock,Ipv6CidrBlockAssociationSet]'

If unsure about your CIDR math, write it out:
- VPC: 10.0.0.0/16 = 10.0.0.0 to 10.0.255.255 (65,536 IPs)
- Subnet /24 = 256 IPs per subnet
- Valid subnets: 10.0.0.0/24, 10.0.1.0/24, ..., 10.0.255.0/24

6Verify CIDR syntax and fix common mistakes

Common CIDR syntax errors that trigger InvalidSubnet.Range:

Correct format:

hcl
cidr_block = "10.0.1.0/24"  # CORRECT

Common mistakes:

hcl
# Missing leading zeros
cidr_block = "10.0.1.0/024"      # WRONG (invalid prefix)

# Wrong notation
cidr_block = "10.0.1.0-10.0.1.255"  # WRONG (use CIDR notation)

# Subnet with host bits set
cidr_block = "10.0.1.128/25"
# This is 10.0.1.128 to 10.0.1.255, but the /25 prefix expects the network
# to end at a /25 boundary. Use 10.0.1.0/25 or 10.0.1.128/25 correctly.

# Using public IP ranges for private subnets
cidr_block = "8.8.8.0/24"  # Public range - won't work for private VPC

Fixing variable interpolation issues:

hcl
# BAD: May cause validation errors during planning
variable "subnet_cidr" {
  type = string
}

resource "aws_subnet" "bad" {
  vpc_id     = aws_vpc.main.id
  cidr_block = var.subnet_cidr  # Terraform can't validate before applying
}

# GOOD: Validate with Terraform functions
resource "aws_subnet" "good" {
  vpc_id     = aws_vpc.main.id
  cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 2, var.subnet_index)
}
7Fix IPv6 CIDR issues

IPv6 errors require specific handling:

hcl
# Step 1: Enable IPv6 on VPC
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  assign_ipv6_cidr_block = true
}

# Step 2: Wait for IPv6 CIDR association
resource "aws_vpc_ipv6_cidr_block_association" "main" {
  vpc_id            = aws_vpc.main.id
  amazon_provided_ipv6_cidr_block = true
}

# Step 3: Create subnet with IPv6
resource "aws_subnet" "example" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"

  # IPv6 CIDR block from VPC
  ipv6_cidr_block = cidrsubnet(aws_vpc.main.ipv6_cidr_block, 8, 1)

  assign_ipv6_address_on_creation = true

  depends_on = [aws_vpc_ipv6_cidr_block_association.main]
}

Don't do this:

hcl
# WRONG: Empty IPv6 CIDR will cause error
resource "aws_subnet" "bad" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  ipv6_cidr_block   = ""  # Error!
}

# Either set a valid block or omit the argument entirely
8Verify the fix

After fixing your Terraform code, validate and apply:

bash
# Validate syntax
terraform validate

# Plan to see what will be created
terraform plan

# Apply the changes
terraform apply

Then verify in AWS:

bash
# List all subnets in your VPC
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-xxxxx" \
  --query 'Subnets[*].[SubnetId,CidrBlock,AvailabilityZone]' \
  --output table

# Or check a specific subnet
aws ec2 describe-subnets --subnet-ids subnet-xxxxx \
  --query 'Subnets[0]'

If Terraform still shows errors, check that you haven't:
- Modified the VPC CIDR block (requires subnet updates)
- Created subnets outside Terraform (leads to state mismatch)
- Used conflicting resource names (check terraform state list)

Advanced notes

### CIDR Block Mathematics

Understanding CIDR notation is critical for avoiding InvalidSubnet.Range errors:

Format: X.X.X.X/prefix
- X.X.X.X = Network address
- /prefix = Number of bits used for the network (0-32)
- Remaining bits = Host addresses

Examples:
- 10.0.0.0/16 = 10.0.0.0 to 10.0.255.255 (65,536 addresses)
- 10.0.0.0/24 = 10.0.0.0 to 10.0.0.255 (256 addresses)
- 10.0.0.0/28 = 10.0.0.0 to 10.0.0.15 (16 addresses - AWS minimum)

AWS Subnet Rules:
- Must be within VPC CIDR block
- Minimum size: /28 (16 addresses)
- Maximum size: /16 (65,536 addresses, same as largest VPC)
- First 4 addresses reserved (network, gateway, DNS, broadcast)
- Last address reserved (broadcast)
- Actual usable IPs per /24 subnet: 256 - 5 = 251

### Secondary CIDR Blocks

Terraform limitations with secondary CIDR blocks:

1. Association delay: AWS takes time to associate secondary CIDR blocks
2. State consistency: Terraform may think CIDR is ready before AWS does
3. Solution: Always add depends_on or run apply twice

### Terraform cidrsubnet() Function Details

hcl
cidrsubnet(prefix, newbits, netnum)

- prefix: VPC CIDR (e.g., "10.0.0.0/16")
- newbits: Additional bits for subnet mask (e.g., 2)
- Original: /16
- Add 2 bits: /18
- netnum: Which subnet (0, 1, 2, ..., 2^newbits - 1)

Example:

hcl
VPC: 10.0.0.0/16

cidrsubnet("10.0.0.0/16", 2, 0)  # = 10.0.0.0/18
cidrsubnet("10.0.0.0/16", 2, 1)  # = 10.0.64.0/18
cidrsubnet("10.0.0.0/16", 2, 2)  # = 10.0.128.0/18
cidrsubnet("10.0.0.0/16", 2, 3)  # = 10.0.192.0/18

### Local and Private IP Ranges

Use these ranges for private subnets (won't route to internet):

- Class A: 10.0.0.0/8 (10.0.0.0 to 10.255.255.255)
- Class B: 172.16.0.0/12 (172.16.0.0 to 172.31.255.255)
- Class C: 192.168.0.0/16 (192.168.0.0 to 192.168.255.255)

Link-local (auto-assigned): 169.254.0.0/16

### Debugging with Terraform

bash
# View computed CIDR blocks
terraform console
> cidrsubnet("10.0.0.0/16", 2, 0)
"10.0.0.0/18"

# Destroy and recreate if stuck
terraform destroy -target aws_subnet.example
terraform apply

# Check state directly
terraform state show aws_subnet.example

### AWS API Validation

InvalidSubnet.Range comes from AWS API validation, not Terraform. When Terraform sends:

json
{
  "SubnetCidrBlock": "10.0.1.0/24",
  "VpcId": "vpc-12345"
}

AWS checks:
1. Is 10.0.1.0/24 a valid CIDR?
2. Is it within the VPC's CIDR blocks?
3. Does it overlap with existing subnets?
4. Is the size between /28 and /16?

If any check fails, you get InvalidSubnet.Range.

Frequently asked questions

What does "Error: Error creating subnet: InvalidSubnet.Range" mean?
When creating an AWS subnet with Terraform, the subnet's CIDR block must be a valid subset of the VPC's CIDR block. Range error indicates that the CIDR block you're trying to assign to your subnet violates AWS subnet requirements. 0/24) - The subnet size is too large (subnets must be at least /28) or uses invalid boundaries - Multiple subnets overlap with each other - Using secondary VPC CIDR blocks before they're fully provisioned - IPv6 CIDR block issues when enabling IPv6 on subnets AWS maintains strict validation to prevent IP address exhaustion and routing conflicts within your VPC.
How do I fix "Error: Error creating subnet: InvalidSubnet.Range"?
The InvalidSubnet.Range error occurs when your Terraform subnet CIDR block is invalid or doesn't fit within your VPC's IP address space. This typically happens when the subnet CIDR is outside the VPC range, overlaps with existing subnets, or when using secondary CIDR blocks before they're fully associated.
What causes "Error: Error creating subnet: InvalidSubnet.Range"?
Subnet CIDR block is outside the VPC's CIDR range (most common) Subnet CIDR size violates AWS limits (must be between /16 and /28) Subnet CIDR overlaps with an existing subnet in the VPC
Is the "Error: Error creating subnet: InvalidSubnet.Range" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading