AWS Overlapping CIDR Fix: Transit Gateway 1:1 NAT Setup, Why Both VPCs Need a Rule, the Route It Replaces, VPN and Direct Connect, Cloud WAN, Pricing and Every Limit
Since October 23, 2026, AWS Transit Gateway and AWS Cloud WAN can connect networks whose CIDRs overlap, without renumbering and without a NAT appliance. You add 1:1 NAT rules to an attachment, and the transit gateway rewrites addresses in both directions: VPC-A's 10.0.0.0/16 becomes 100.64.0.0/16 on the way out, and replies come back to the real address on their own. One command sets it up: aws ec2 modify-transit-gateway-attachment-nat-configuration. The part almost everyone gets wrong comes next. If two VPCs both use 10.0.0.0/16, translating only one of them does not work. The untranslated VPC sends its replies to an address inside its own range, and its route table keeps that traffic local, so the replies never reach the transit gateway. You have to give each overlapping network its own NAT range. The second surprise: the moment you save a rule on a VPC attachment, the transit gateway replaces that VPC's real-address route with the NAT one, and anything that reached the VPC by its real addresses loses the path. This guide covers setup, routing, VPN and Direct Connect, Cloud WAN, pricing, limits and the traps.
Jake bought a second repair shop in October. The deal was simple; the network was not. The other shop's booking system runs in its own AWS account, in a VPC on 10.0.0.0/16, and Jake's inventory system sits in a VPC on exactly the same range. "So the two apps can't talk because somebody picked the same number?" Jake asked. "Two somebodies," Ethan said. "Last week the answer was a month of renumbering. This week it is four rules on a transit gateway, if you put them on both sides."
New to AWS networking? A VPC is your own private network inside AWS, and a CIDR such as 10.0.0.0/16 is the block of addresses it uses; our plain-English VPC guide covers both. A transit gateway is a hub that connects many VPCs, VPNs and Direct Connect links through one set of route tables. If routing on a transit gateway is new to you, read our Transit Gateway routing guide first, because 1:1 NAT changes which routes appear in those tables.
What is Transit Gateway 1:1 NAT?
1:1 NAT is a mapping from one CIDR block to another of the same size, set on a single attachment. Every address keeps its position: if 10.10.100.0/24 maps to 100.64.100.0/24, then 10.10.100.5 always becomes 100.64.100.5. Only the network part changes; the host part (here the last number) stays the same, and ports are never touched.
Each rule works in both directions, so you never write a separate return rule:
- Source NAT (SNAT): traffic arriving from the attachment with a source address in the original CIDR leaves the transit gateway with the matching NAT address.
- Destination NAT (DNAT): traffic sent to the attachment with a destination address in the NAT CIDR is rewritten back to the original address before delivery.
Because the mapping is fixed, translation needs no connection table. Replies are translated without any state, and other networks can start connections to the NAT addresses too, which ordinary NAT gateways cannot do. That makes it useful for three jobs:
- Overlapping addresses after a merger or acquisition, with a partner network over Site-to-Site VPN, with another cloud, or between VPCs that different teams numbered on their own.
- Hiding your real addressing from partners or other business units, who only ever see the NAT range.
- Running out of RFC 1918 space, by using the shared address space
100.64.0.0/10(RFC 6598, the range carriers use for CGNAT) as NAT ranges.
Here is what it supports on October 24, 2026:
| Item | Transit Gateway 1:1 NAT |
|---|---|
| Launched | October 23, 2026, in every commercial Region where Transit Gateway and Cloud WAN run |
| Attachments with NAT | VPC, Direct Connect gateway, Site-to-Site VPN (including Private IP VPN), Connect, intra-Region and inter-Region peering, VPN Concentrator |
| No NAT on | Client VPN, Network Function attachments, Cloud WAN peering and route table attachments |
| Rules | Up to 50 per attachment; rule numbers 1 to 32766; no priority order |
| NAT ranges | RFC 1918 (10/8, 172.16/12, 192.168/16) or 100.64.0.0/10; same prefix length as the original |
| Protocol | IPv4 only; IPv6 passes through untranslated |
| Who can configure it | Only the account that owns the transit gateway |
| Tools | Console (1:1 NAT tab on the attachment), AWS CLI, SDKs, CloudFormation |
| Monitoring | CloudWatch BytesInNAT, BytesOutNAT, PacketsInNAT, PacketsOutNAT; EventBridge events |
"So nothing gets installed in my VPC?" Jake asked. "No box, no appliance, no extra subnet," Ethan said. "The rewrite happens inside the transit gateway, on the attachment."
Why overlapping CIDRs broke Transit Gateway until now
A transit gateway route table can hold only one route for a given prefix. When you attach a second VPC whose CIDR overlaps one that is already attached, the transit gateway does not propagate the newcomer's CIDR. The attachment shows available, everything looks healthy, and the second VPC simply has no route. Our route-not-propagating guide walks through that symptom in detail.
Until this week there were four ways out, and none of them was pleasant:
- Renumber one network. The clean answer, and often a project measured in months, because addresses live in firewall rules, DNS, application settings and partner allowlists.
- Private NAT gateways with a secondary CIDR. You give each VPC an extra, non-overlapping range, put private NAT gateways in it, and route only those ranges through the transit gateway. It works, but only outbound: the far side cannot start a connection to you, and you pay for NAT gateways in every Availability Zone (AZ) of every VPC involved.
- PrivateLink. Publish one service behind a Network Load Balancer and consume it as an endpoint. Excellent for one service, clumsy for "these two networks need to talk".
- NAT appliances. Firewalls or routers you run yourself, with the patching, scaling and failover that implies.
1:1 NAT replaces most of those cases with rules on the attachments you already pay for. Renumbering is still the right long-term answer for networks you control, and we come back to that in the comparison.
The trap: translate both overlapping networks, not just one
The obvious plan is to leave your own VPC alone and translate the newcomer. It fails, and the reason has nothing to do with the transit gateway.
Picture Jake's two VPCs, both on 10.0.0.0/16. Ethan puts a rule only on the booking VPC (VPC-B), mapping it to 100.65.0.0/16. An inventory server in VPC-A at 10.0.0.5 connects to a booking server at its NAT address, 100.65.0.1. The packet reaches VPC-B as src=10.0.0.5, dst=10.0.0.1. The booking server replies to 10.0.0.5, and that is where it breaks: 10.0.0.5 is inside VPC-B's own CIDR, and a VPC always delivers traffic for its own range locally, through the local route. The reply stays inside VPC-B, looking for a host that is not there. It never reaches the transit gateway.
The fix is to give each overlapping network its own NAT range:
| Attachment | Real CIDR (MatchSourceCidr) | NAT CIDR | Others reach it at |
|---|---|---|---|
| VPC-A (inventory) | 10.0.0.0/16 | 100.64.0.0/16 | 100.64.x.y |
| VPC-B (booking) | 10.0.0.0/16 | 100.65.0.0/16 | 100.65.x.y |
Now follow the same connection. VPC-A's 10.0.0.5 sends to 100.65.0.1. The transit gateway applies VPC-A's rule to the source (10.0.0.5 becomes 100.64.0.5), finds the route for 100.65.0.0/16, and applies VPC-B's rule to the destination (100.65.0.1 becomes 10.0.0.1). The booking server sees src=100.64.0.5 and replies to it. That address is outside its own CIDR, so the reply follows the VPC route to the transit gateway, which reverses both rewrites. Each server uses its real address, and each network reaches the other at the other's NAT range.
The same logic applies to anything that overlaps: a partner's office on 192.168.1.0/24 and your VPC with the same block, or an on-premises network and a VPC. Translating one side is fine when the ranges do not overlap and you only want to hide addresses. When they overlap, translate both. "It feels like double the work," Jake said. "It's two rules," Ethan said. "One per side, and then the reply has somewhere to go."
The second trap: saving a rule replaces the VPC's real route
On a VPC attachment, when a rule's MatchSourceCidr exactly matches one of the VPC's CIDRs, the transit gateway does more than translate. It removes the VPC's propagated route for 10.0.0.0/16 and installs a route for the NAT CIDR instead, with the route type system. Here is a transit gateway route table before and after, with a third VPC (VPC-C, 172.16.0.0/16) that has no rules:
| Prefix | Attachment | Route type |
|---|---|---|
| Before NAT (VPC-B overlaps VPC-A, so VPC-B is not propagated at all) | ||
10.0.0.0/16 | VPC-A | propagated |
172.16.0.0/16 | VPC-C | propagated |
| After NAT on VPC-A and VPC-B | ||
100.64.0.0/16 | VPC-A | system |
100.65.0.0/16 | VPC-B | system |
172.16.0.0/16 | VPC-C | propagated |
Look at what disappeared: 10.0.0.0/16. If VPC-C, your office VPN or a Direct Connect site was reaching VPC-A at 10.0.x.y yesterday, it loses that path the moment the rule saves. From then on, everyone reaches VPC-A at 100.64.x.y, so every peer's route tables, security group rules, firewall allowlists and DNS records have to move to the NAT range. That is why the order of work matters, and why the migration plan below puts those updates first.
This bites hardest on the network you already run. Jake's inventory VPC is reached by both shops' tills over VPN. Translate it, and the tills need the new addresses on the same evening. Ethan's answer was to translate the inventory VPC with a NAT range that the tills learn over BGP before the switch, and to do it at 9 p.m. on a Sunday.
How to set up 1:1 NAT for two overlapping VPCs, step by step
This walkthrough connects two VPCs that both use 10.0.0.0/16 through one transit gateway. You need the account that owns the transit gateway; if it is shared through AWS Resource Access Manager, the accounts that own the VPCs cannot see or change NAT settings.
- Reserve a NAT block. Pick a range used nowhere in your AWS estate, your offices or your partners, and carve one slice per overlapping network. A slice of
100.64.0.0/10is a sensible default: it is private, rarely used inside companies, and big enough for 64 networks of/16. Here: VPC-A gets100.64.0.0/16, VPC-B gets100.65.0.0/16. - Attach both VPCs to the transit gateway as usual, and associate them with a route table they both propagate to. VPC-B's CIDR will not appear yet, which is expected.
- Check that appliance mode is off on both VPC attachments. NAT cannot be enabled on an attachment with appliance mode on.
- Enable NAT on VPC-A's attachment:
aws ec2 modify-transit-gateway-attachment-nat-configuration \ --transit-gateway-attachment-id tgw-attach-0aaaaaaaaaaaaaaaa \ --nat-gateway-support enable \ --nat-gateway-rules '[{"RuleNumber":100,"MatchSourceCidr":"10.0.0.0/16","NatCidr":"100.64.0.0/16"}]' - Enable NAT on VPC-B's attachment with its own range:
aws ec2 modify-transit-gateway-attachment-nat-configuration \ --transit-gateway-attachment-id tgw-attach-0bbbbbbbbbbbbbbbb \ --nat-gateway-support enable \ --nat-gateway-rules '[{"RuleNumber":100,"MatchSourceCidr":"10.0.0.0/16","NatCidr":"100.65.0.0/16"}]' - Wait for both to settle. Changes apply in the background while the attachment stays
available. Run the check below until support readsenabledand every rule readsactivated:aws ec2 get-transit-gateway-attachment-nat-configuration \ --transit-gateway-attachment-id tgw-attach-0aaaaaaaaaaaaaaaa \ --query '{Support:NatGatewaySupport,Rules:NatGatewayRules[].[RuleNumber,State]}' - Update the VPC route tables. In VPC-A's subnet route tables, send
100.65.0.0/16to the transit gateway. In VPC-B's, send100.64.0.0/16to the transit gateway. Each VPC routes to the other side's NAT range; nobody routes to10.0.0.0/16through the transit gateway any more. - Update security groups and network ACLs. VPC-B now sees VPC-A's traffic arriving from
100.64.0.0/16, so its inbound rules must allow that range, and the same in reverse. Rules that allow10.0.0.0/16do not match translated traffic. - Test with the NAT address. From a VPC-A instance, connect to a VPC-B instance at its NAT address: VPC-B's
10.0.0.1is100.65.0.1from VPC-A's side.
For scripts, this small loop waits until a change has finished. It reads the support state and the state of every rule, and stops when nothing is still moving:
#!/bin/sh
# wait-nat.sh tgw-attach-ID [max-seconds]: poll until 1:1 NAT changes have settled.
ATT=$1; MAX=${2:-600}; T=0
while :; do
OUT=$(aws ec2 get-transit-gateway-attachment-nat-configuration \
--transit-gateway-attachment-id "$ATT" \
--query '[NatGatewaySupport, join(`,`, NatGatewayRules[].State || `[]`)]' --output text) || exit 1
SUP=$(echo "$OUT" | cut -f1); STATES=$(echo "$OUT" | cut -f2)
echo "$(date -u +%H:%M:%S) support=$SUP rules=${STATES:-none}"
case "$SUP" in enabling|disabling) ;; *)
echo "$STATES" | grep -qE 'pending|deleting' || { echo "settled"; exit 0; } ;;
esac
T=$((T+15)); [ "$T" -ge "$MAX" ] && { echo "still changing after ${MAX}s"; exit 2; }
sleep 15
done
We ran its query against sample responses for the four states that matter: a change in progress returns ['enabling', 'pending,activated'], a finished one ['enabled', 'activated,activated'], and an attachment whose rules were cleared returns ['disabled', ''] whether the response has an empty rule list or none at all, so the loop ends cleanly in every case.
"How long does the switch take?" Jake asked. "A short while, and there can be a moment in the middle where new addresses drop packets," Ethan said. "So we do it when the tills are closed."
Setting it up in the console
- Open the VPC console and choose Transit gateway attachments.
- Select the attachment, open its 1:1 NAT tab and choose Manage 1:1 NAT (also under Actions).
- Tick Enable NAT Gateway support.
- Under NAT rules, choose Add rule and enter a rule number (1 to 32766), the Match source CIDR and the NAT CIDR.
- Choose Save changes, then come back to the 1:1 NAT tab until it shows Enabled and every rule shows Activated.
Two console details catch people. First, the form is the whole rule set: when you save, the rules on screen replace every rule on the attachment, so a rule you delete from the form is deleted for real. Second, you cannot save while support shows Enabling or Disabling; wait for it to settle, then edit again.
CloudFormation: one resource per attachment
In CloudFormation, NAT is its own resource, AWS::EC2::TransitGatewayAttachmentNatConfiguration, not a property of the attachment resource. Each resource holds the full configuration for one attachment, and the stack must run in the account that owns the transit gateway:
Resources:
InventoryVpcNat:
Type: AWS::EC2::TransitGatewayAttachmentNatConfiguration
Properties:
TransitGatewayAttachmentId: !Ref InventoryVpcAttachment
NatGatewaySupport: enable
NatGatewayRules:
- RuleNumber: 100
MatchSourceCidr: 10.0.0.0/16
NatCidr: 100.64.0.0/16
BookingVpcNat:
Type: AWS::EC2::TransitGatewayAttachmentNatConfiguration
Properties:
TransitGatewayAttachmentId: !Ref BookingVpcAttachment
NatGatewaySupport: enable
NatGatewayRules:
- RuleNumber: 100
MatchSourceCidr: 10.0.0.0/16
NatCidr: 100.65.0.0/16
Keeping both sides in one template is a good habit, because the pair only works together. The NatGatewayRules list in the template is the complete set, exactly as with the CLI, so editing it replaces every rule on the attachment; review the change set before you run it. If the CloudFormation basics are new, our CloudFormation stack guide explains stacks and change sets.
NAT rule limits: what a valid rule looks like
The API checks each rule, but only within one attachment. Here is the full list of conditions:
| Condition | Detail | Checked by AWS? |
|---|---|---|
| Equal prefix lengths | A /24 maps to a /24, a /16 to a /16 | Yes |
| NAT range type | Inside 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 or 100.64.0.0/10 | Yes |
| Match range | Cannot overlap multicast (224.0.0.0/4) or link-local (169.254.0.0/16) | Yes |
| No overlap on one attachment | No match or NAT CIDR may overlap another rule's match or NAT CIDR on the same attachment | Yes |
| Count and numbers | Up to 50 rules; unique numbers from 1 to 32766; numbers are labels, not priorities | Yes |
| No overlap across your network | A NAT range must not overlap any other attachment's NAT range, any untranslated attachment's CIDR, or any VPC or office that must reach it | No, that part is on you |
The last row is the dangerous one. Say VPC-A is 10.0.0.0/16 and you pick 10.0.5.0/24 as a NAT range for someone else. VPC-A can never reach it: those addresses sit inside VPC-A's own range, so VPC-A delivers the traffic locally. The API accepts the rule happily, because the conflict is between two different networks. The same goes for an office that routes the range internally, or two attachments that were each given the same slice by two different engineers.
Because rules on one attachment can never overlap, every address matches at most one rule. That is why rule numbers carry no priority: there is never a contest to settle. Use them as labels with gaps (100, 200, 300), so a later rule can slot in between.
Lab: a NAT plan checker that catches what the API misses
We wrote a small checker that reads a plan as JSON (attachments, their real CIDRs, their rules and any other networks that must reach the NAT ranges) and applies every condition above, plus the cross-network checks the API leaves to you. It makes no AWS calls; it runs before you touch anything. The full script is in the code block below. Here is its output for three plans.
The correct plan from this guide (both VPCs translated, VPC-C untouched):
INFO vpc-a: saving replaces the propagated route for 10.0.0.0/16 with 100.64.0.0/16; anything that reaches vpc-a by its real address loses the path
INFO vpc-b: saving replaces the propagated route for 10.0.0.0/16 with 100.65.0.0/16; anything that reaches vpc-b by its real address loses the path
The one-sided plan from the trap:
INFO vpc-b: saving replaces the propagated route for 10.0.0.0/16 with 100.65.0.0/16; anything that reaches vpc-b by its real address loses the path
ERROR vpc-a 10.0.0.0/16 overlaps vpc-b 10.0.0.0/16 but only one side is translated; vpc-a sends its replies to an address inside its own CIDR and the VPC keeps them local. Translate both.
A plan with the common mistakes in one place: a /24 rule inside a /16 VPC, a mismatched prefix, a public NAT range, an inspection VPC with appliance mode, a static VPN, a Client VPN and two ranges that collide across attachments (trimmed to the key lines):
WARN vpc-b rule 100: 10.0.1.0/24 is not an exact VPC CIDR, so no route is installed for 10.0.5.0/24; add a static TGW route for 10.0.5.0/24 to this attachment or replies are dropped
ERROR vpc-b rule 200: 10.0.2.0/24 is /24 but 100.66.0.0/16 is /16; 1:1 NAT needs equal prefix lengths
ERROR vpc-b rule 300: NAT CIDR 8.8.8.0/24 is not RFC 1918 or 100.64.0.0/10
ERROR inspection: appliance mode is on; NAT cannot be enabled until you turn it off
WARN branch-vpn rule 10: vpn-static never gets a system route; add a static route for 100.64.10.0/24 or have the peer advertise it
ERROR laptops: client-vpn attachments do not support 1:1 NAT
ERROR vpc-a: NAT CIDR 100.64.0.0/16 overlaps 100.64.10.0/24 used by branch-vpn (AWS only checks inside one attachment)
ERROR vpc-b: NAT CIDR 10.0.5.0/24 overlaps 10.0.0.0/16 used by vpc-a (AWS only checks inside one attachment)
The last two lines are the ones worth the script. The API would accept every one of those rules, and the collisions would only show up as traffic going to the wrong place. Save the script as tgw_nat_plan_check.py and run python3 tgw_nat_plan_check.py plan.json:
#!/usr/bin/env python3
"""Check a Transit Gateway 1:1 NAT plan before you save it (no AWS calls)."""
import ipaddress as ip, json, sys
ALLOWED = [ip.ip_network(n) for n in ('10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '100.64.0.0/10')]
BANNED_SRC = [ip.ip_network('224.0.0.0/4'), ip.ip_network('169.254.0.0/16')]
NO_NAT_TYPES = {'client-vpn', 'network-function', 'cloudwan-peering', 'cloudwan-route-table'}
SYSTEM_ROUTE_NEVER = {'vpn-static', 'peering', 'connect', 'vpn-concentrator'}
def check(plan):
out, atts, nat_cidrs = [], plan['attachments'], {}
for a in atts:
name, kind, rules = a['name'], a['type'], a.get('rules', [])
real = [ip.ip_network(c) for c in a.get('cidrs', [])]
if rules and kind in NO_NAT_TYPES:
out.append(f'ERROR {name}: {kind} attachments do not support 1:1 NAT')
if rules and a.get('appliance_mode'):
out.append(f'ERROR {name}: appliance mode is on; NAT cannot be enabled until you turn it off')
if len(rules) > 50:
out.append(f'ERROR {name}: {len(rules)} rules; the limit is 50 per attachment')
seen_nums, mine = set(), []
for r in rules:
n, src, dst = r['RuleNumber'], ip.ip_network(r['MatchSourceCidr']), ip.ip_network(r['NatCidr'])
if not 1 <= n <= 32766: out.append(f'ERROR {name} rule {n}: rule number must be 1-32766')
if n in seen_nums: out.append(f'ERROR {name} rule {n}: duplicate rule number')
seen_nums.add(n)
if src.prefixlen != dst.prefixlen:
out.append(f'ERROR {name} rule {n}: {src} is /{src.prefixlen} but {dst} is /{dst.prefixlen}; 1:1 NAT needs equal prefix lengths')
if not any(dst.subnet_of(x) for x in ALLOWED):
out.append(f'ERROR {name} rule {n}: NAT CIDR {dst} is not RFC 1918 or 100.64.0.0/10')
if any(src.overlaps(b) for b in BANNED_SRC):
out.append(f'ERROR {name} rule {n}: match CIDR {src} overlaps multicast or link-local')
for prev_n, c in mine:
for x in (src, dst):
if x.overlaps(c): out.append(f'ERROR {name} rule {n}: {x} overlaps another CIDR on this attachment (rule {prev_n})')
mine += [(n, src), (n, dst)]
if kind == 'vpc' and src not in real:
out.append(f'WARN {name} rule {n}: {src} is not an exact VPC CIDR, so no route is installed for {dst}; add a static TGW route for {dst} to this attachment or replies are dropped')
if kind in SYSTEM_ROUTE_NEVER:
out.append(f'WARN {name} rule {n}: {kind} never gets a system route; add a static route for {dst} or have the peer advertise it')
nat_cidrs.setdefault(name, []).append(dst)
if kind == 'vpc':
for r in rules:
if ip.ip_network(r['MatchSourceCidr']) in real:
out.append(f'INFO {name}: saving replaces the propagated route for {r["MatchSourceCidr"]} with {r["NatCidr"]}; anything that reaches {name} by its real address loses the path')
for a in atts: # cross-attachment checks the API leaves to you
for d in nat_cidrs.get(a['name'], []):
for b in atts:
if b is a: continue
for c in [ip.ip_network(x) for x in b.get('cidrs', [])] + nat_cidrs.get(b['name'], []):
if d.overlaps(c): out.append(f'ERROR {a["name"]}: NAT CIDR {d} overlaps {c} used by {b["name"]} (AWS only checks inside one attachment)')
for other in plan.get('other_networks', []):
if d.overlaps(ip.ip_network(other)): out.append(f'ERROR {a["name"]}: NAT CIDR {d} overlaps {other}, a network that must reach it')
for i, a in enumerate(atts): # identical CIDRs where only one side is translated
for b in atts[i+1:]:
for ca in a.get('cidrs', []):
for cb in b.get('cidrs', []):
if ip.ip_network(ca).overlaps(ip.ip_network(cb)):
ta = any(ip.ip_network(r['MatchSourceCidr']).overlaps(ip.ip_network(ca)) for r in a.get('rules', []))
tb = any(ip.ip_network(r['MatchSourceCidr']).overlaps(ip.ip_network(cb)) for r in b.get('rules', []))
if ta != tb:
plain = b['name'] if ta else a['name']
out.append(f'ERROR {a["name"]} {ca} overlaps {b["name"]} {cb} but only one side is translated; {plain} sends its replies to an address inside its own CIDR and the VPC keeps them local. Translate both.')
elif not ta:
out.append(f'ERROR {a["name"]} {ca} overlaps {b["name"]} {cb} and neither is translated; the later attachment is not propagated')
return out or ['OK no problems found']
if __name__ == '__main__':
for line in check(json.load(open(sys.argv[1]))): print(line)
A plan file looks like this (types: vpc, vpn-bgp, vpn-static, dxgw, peering, connect, vpn-concentrator, client-vpn):
{"attachments": [
{"name": "vpc-a", "type": "vpc", "cidrs": ["10.0.0.0/16"],
"rules": [{"RuleNumber": 100, "MatchSourceCidr": "10.0.0.0/16", "NatCidr": "100.64.0.0/16"}]},
{"name": "vpc-b", "type": "vpc", "cidrs": ["10.0.0.0/16"],
"rules": [{"RuleNumber": 100, "MatchSourceCidr": "10.0.0.0/16", "NatCidr": "100.65.0.0/16"}]},
{"name": "vpc-c", "type": "vpc", "cidrs": ["172.16.0.0/16"]}],
"other_networks": ["192.168.0.0/16"]}
How routing works with 1:1 NAT, attachment by attachment
After translation, other networks reach an attachment through its NAT range, so a route to that range has to exist in every transit gateway route table that sends traffic there. Whether the transit gateway adds that route for you depends on the attachment type, through a setting called NatSystemRouteSupport:
| Attachment type | NatSystemRouteSupport | How the NAT range becomes reachable |
|---|---|---|
| VPC | Always enable | The VPC CIDR's propagated route is replaced by the NAT route, but only when the rule exactly matches a VPC CIDR |
| Direct Connect gateway, Site-to-Site VPN with BGP | enable (default) or disable | The transit gateway installs the route, or you advertise the NAT range yourself |
| Site-to-Site VPN with static routing, static peering | Always disable | Add a static route for the NAT range to the attachment |
| Connect, VPN Concentrator | Always disable | Your BGP peers advertise the NAT range |
Three routing details decide whether your design works:
- A partial rule on a VPC gets no route. If the VPC is
10.0.0.0/16and the rule matches only10.0.1.0/24, the API accepts it and translation happens, but nothing replaces or adds a route. Until you add a static transit gateway route for the NAT range pointing at the VPC attachment, traffic to the NAT addresses, including replies to translated traffic, goes nowhere. This is the quietest failure in the feature. - A static route beats a NAT route. For the same prefix, a
systemroute ranks below astaticroute and above prefix list references and propagated routes. Longest-prefix match still comes first. So an old static route for100.64.0.0/16that someone created last year still wins, and enabling NAT never overrides it. - NAT routes appear only in route tables the attachment propagates to. If another route table needs to reach the NAT range, add a static route there.
In route searches and exports (SearchTransitGatewayRoutes, ExportTransitGatewayRoutes), routes the transit gateway created for NAT show the type system. A NAT range that you advertise from your own BGP peers shows as propagated; the type tells you who created the route, not whether NAT is involved.
"Why would a /24 rule be useful at all?" Jake asked. "When only one subnet clashes," Ethan said. "You translate just that slice and leave the rest of the VPC on its real addresses. You just have to add the route by hand."
Partners over VPN and offices over Direct Connect
The partner case is where 1:1 NAT earns its keep. A supplier's office on 192.168.1.0/24 connects over Site-to-Site VPN, and you already use 192.168.1.0/24 in a VPC. With BGP on the VPN, you have two ways to make the NAT range reachable.
System routes on (the default). Put a rule on the VPN attachment, say 192.168.1.0/24 to 100.66.1.0/24 (and, because the ranges clash, a rule on your own VPC too, as in the trap), and the transit gateway installs a system route for 100.66.1.0/24. That route stays active only while the partner keeps advertising a route that overlaps the original range: the same 192.168.1.0/24, something more specific, or a summary. If the partner stops advertising it, perhaps because someone "cleans up" the overlapping announcement, the NAT route turns into a blackhole and traffic to the partner is dropped. The partner's original routes stay in the table next to the NAT route either way.
System routes off. Set --nat-system-route-support disable and have the partner's router advertise 100.66.1.0/24 instead. The transit gateway learns it as a propagated route. In this mode the partner can stop advertising the original range, which is cleaner when that range collides with one of yours, and you can use BGP attributes as you would on any route (AS-path prepending for active and standby, identical attributes for ECMP).
aws ec2 modify-transit-gateway-attachment-nat-configuration \
--transit-gateway-attachment-id tgw-attach-0ccccccccccccccc0 \
--nat-gateway-support enable \
--nat-system-route-support disable \
--nat-gateway-rules '[{"RuleNumber":100,"MatchSourceCidr":"192.168.1.0/24","NatCidr":"100.66.1.0/24"}]'
Pick one mode and keep the partner's behavior consistent with it. The combination to watch for is "system routes on" plus "partner stopped advertising the original": it looks tidy and drops everything. A static VPN never gets a system route, so add a static route for the NAT range that targets the VPN attachment. Direct Connect gateway attachments follow the same two modes as BGP VPN; if you are still choosing between them, our Direct Connect guide covers the costs.
For a Connect attachment (an SD-WAN appliance), you can put NAT on the Connect attachment or on its transport attachment, never both. Enabling it on the second returns an InvalidParameterValue error. To move it, disable it on the first and wait for disabled before enabling on the other.
DNS: the step nobody puts on the plan
Every server in Jake's booking VPC has a DNS name that resolves to its real 10.0.x.y address. From the inventory VPC, that real address is useless: it sits inside the inventory VPC's own range and stays local. Clients in VPC-A must connect to VPC-B's NAT addresses, so they need names that resolve to 100.65.x.y.
1:1 NAT rewrites packet headers, not DNS answers. A few ways to handle it:
- A private hosted zone for the "other side's view". Create a Route 53 private hosted zone, associate it only with VPC-A, and add records that point VPC-B's service names to their NAT addresses (
booking.internalto100.65.0.20). Because host bits are preserved, each NAT address is simply the real one with the network part swapped, which makes the records easy to generate. - Load balancers in front of services. If VPC-B exposes services through internal load balancers, their addresses change when nodes are replaced, so generating records from real addresses goes stale. For a handful of services, PrivateLink can be the simpler choice.
- Careful with shared zones. If both VPCs are associated with the same private hosted zone, clients in VPC-A get VPC-B's real addresses, which is the wrong answer for them.
Our Route 53 vs Route 53 Resolver guide explains private hosted zones and forwarding rules, and the VPC peering DNS guide covers why a name can resolve to an address you cannot reach.
"So the network works, but nobody can find anything until the names change," Jake said. "Exactly," Ethan said. "The routes take an evening. The names take a spreadsheet."
Security groups, network ACLs and logs see the NAT address
After translation, the receiving side sees the sender's NAT address as the source. That changes three things:
- Security groups: VPC-B's inbound rules must allow
100.64.0.0/16(VPC-A's NAT range), not10.0.0.0/16. Write these as CIDR rules for the NAT range. - Network ACLs: the same, in both directions, because network ACLs are stateless. Our security group vs NACL guide shows the return-port rules.
- Logs and audits: VPC Flow Logs in VPC-B record the NAT source address. Keep a mapping (the rule table is enough, because host bits carry over) so whoever reads the logs can turn
100.64.0.5back into VPC-A's10.0.0.5.
There is also a security upside: partners and other business units only ever see your NAT range. Your internal addressing never appears in their firewall logs.
What 1:1 NAT does not do
- No IPv6. IPv6 traffic passes through untranslated.
- No port translation. It is 1:1, not many-to-one. Each original address needs its own NAT address, so a
/16needs a whole/16of NAT space. If you need many hosts to share a few addresses, that is a NAT gateway's job. - No appliance mode on the same attachment. If your inspection VPC attachment has appliance mode on, you cannot enable NAT on that attachment. Put the NAT rules on the spoke attachments instead; the firewall then sees NAT addresses, so write its rules for those.
- Not on Client VPN, Network Function attachments, or Cloud WAN peering and route table attachments.
- Not on both a Connect attachment and its transport.
- Owner only. In a transit gateway shared through Resource Access Manager, only the owner account can view or modify NAT. The VPC owner's account cannot even read it.
- Describe permissions are not enough.
ec2:Describe*does not includeec2:GetTransitGatewayAttachmentNatConfiguration, so a read-only role built on Describe actions cannot see NAT settings. - Brief traffic loss during changes. Translation and routes are updated separately and can take effect at slightly different moments; for a short time, traffic to new NAT addresses can drop.
IAM permissions for 1:1 NAT
Two IAM actions cover the Transit Gateway side. A role that manages NAT needs both; an auditing role needs only the second:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ManageTgwNat",
"Effect": "Allow",
"Action": [
"ec2:ModifyTransitGatewayAttachmentNatConfiguration",
"ec2:GetTransitGatewayAttachmentNatConfiguration"
],
"Resource": "*"
}
]
}
Run both from the account that owns the transit gateway. If your existing network-admin role only lists ec2:Describe* and route-table actions, add these explicitly; wildcard ec2:Get* also covers the read action.
Because one save can cut off every peer of a VPC, it is worth limiting who can change NAT at all. In AWS Organizations, a service control policy can deny the modify action to everyone except your network role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "OnlyNetworkTeamChangesNat",
"Effect": "Deny",
"Action": "ec2:ModifyTransitGatewayAttachmentNatConfiguration",
"Resource": "*",
"Condition": {
"ArnNotLike": { "aws:PrincipalArn": "arn:aws:iam::*:role/NetworkAdmin" }
}
}
]
}
Attach it to the organizational unit that holds the network account, try a change with a non-admin role first to see the deny, and leave the read action open to auditors so they can confirm what is configured. "So even I can't break it by accident?" Jake asked. "Not unless you borrow my role," Ethan said.
1:1 NAT on Cloud WAN: same idea, different API
Cloud WAN uses the same mechanism through the Network Manager API: UpdateAttachmentNatConfiguration to change it and ListAttachmentNatConfigurations to read it, run by the core network owner. The concepts match the Transit Gateway version, but four details differ, and they break scripts copied from one to the other:
| Detail | Transit Gateway (EC2 API) | Cloud WAN (Network Manager API) |
|---|---|---|
| Turn it on | enable / disable (lower case); state reads enabled | ENABLE / DISABLE (upper case); state reads ENABLED |
| System routes setting | String: enable / disable | Boolean: true / false |
| Remove every rule | --reset-nat-gateway-rules (cannot be combined with a rule list) | Send an empty rule list |
| Pending attachments | Not applicable | Settings on an attachment awaiting acceptance are stored and applied after acceptance (state PENDING_ATTACHMENT_ACCEPTANCE) |
In both, the rule list you send replaces the existing rules, so always send the complete set. On Cloud WAN, NAT system routes have the route type SYSTEM, and translation happens whether or not system routes are on.
On Cloud WAN, 1:1 NAT is a paid feature billed at Regional NAT gateway rates, and your normal Cloud WAN attachment and data processing charges do not change. More on cost below.
Lab: what the SDK catches, and what it lets through
Before writing automation, we checked how boto3 1.43.118, a release that already includes these APIs, validates the calls, using botocore's Stubber so no request leaves the machine. The results matter if you build rule lists in code:
| Call | Result in the SDK |
|---|---|
| EC2: enable plus one rule | Accepted |
EC2: RuleNumber as the string "100" | Rejected locally: Invalid type for parameter NatGatewayRules[0].RuleNumber ... valid types: <class 'int'> |
EC2: a rule with no NatCidr | Accepted locally; the SDK does not mark rule fields as required, so the mistake only surfaces as a service error |
Cloud WAN: a rule with no NatCidr | Rejected locally: Missing required parameter in NatGatewayRules[0]: "NatCidr" |
Cloud WAN: NatSystemRouteSupport="enable" (the EC2 habit) | Rejected locally: Invalid type for parameter NatSystemRouteSupport, value: enable ... valid types: <class 'bool'> |
If that automation runs in AWS Lambda, bundle a current boto3 with it. The Lambda Python 3.13 base image built on October 13, 2026 ships boto3 1.42.97, which has no get_transit_gateway_attachment_nat_configuration or modify_transit_gateway_attachment_nat_configuration at all; calling them there raises an AttributeError, because the APIs arrived after that SDK release.
The practical lesson: on the Transit Gateway side, validate your own rule objects (all three fields present, integers for rule numbers) before you call the API, or run the plan checker above. And when you reuse a rule-building function for Cloud WAN, convert the enable flags and the system-route setting rather than passing them through.
Monitoring translated traffic in CloudWatch
Four new metrics in the AWS/TransitGateway namespace count only translated traffic. The existing BytesIn, BytesOut, PacketsIn and PacketsOut still count everything:
BytesInNATandPacketsInNAT: traffic received from an attachment whose source was translated by that attachment's rules.BytesOutNATandPacketsOutNAT: traffic sent to an attachment whose destination was translated by that attachment's rules.
Each NAT metric counts against the attachment whose rule applied. Traffic from an untranslated VPC to a translated VPC's NAT address shows up in the destination attachment's PacketsOutNAT, not in the source's PacketsInNAT. With both sides translated, as in this guide, one packet counts in the source attachment's PacketsInNAT and the destination attachment's PacketsOutNAT. The only meaningful statistic is Sum, at 60-second resolution, with the TransitGatewayAttachment dimension for per-attachment graphs.
Two alarms are worth setting on day one. Alarm on PacketDropCountBlackhole above zero for the transit gateway, which catches the VPN case where a NAT route turned into a blackhole. And watch PacketsOutNAT on each translated VPC attachment: if it falls to zero while PacketsIn on the peer stays busy, traffic is arriving at the wrong address. If CloudWatch is new, our plain-English CloudWatch guide covers alarms. 1:1 NAT also publishes events to EventBridge, which you can route to a chat channel so the team sees NAT activity as it happens.
Transit Gateway 1:1 NAT pricing
The Transit Gateway charges you already pay do not change. In US East (N. Virginia), on October 24, 2026, Transit Gateway costs $0.05 per attachment-hour for VPC, VPN, Direct Connect, Connect and peering attachments, and $0.02 per GB of data processed.
1:1 NAT is a separate, paid feature. It is billed at Regional NAT gateway rates, which adds an hourly charge and a data processing charge on top of the transit gateway charges. A Regional NAT gateway in US East (Ohio) costs $0.045 per hour per Availability Zone and $0.045 per GB processed. On October 24, AWS had not yet published a separate 1:1 NAT price line for transit gateway attachments, so the exact hourly unit (per attachment, or per Availability Zone the attachment uses) was not public yet. Check the Amazon VPC section of your bill a day after you enable it.
The data processing part is the one that grows. Every translated gigabyte pays the Transit Gateway's $0.02 plus the NAT rate of $0.045, so about $0.065 per GB instead of $0.02. For Jake's two shops, moving about 200 GB a month between the apps:
| Item | Monthly (730 hours) |
|---|---|
| 2 VPC attachments at $0.05 per hour | $73.00 |
| Transit Gateway data processing, 200 GB at $0.02 | $4.00 |
| NAT data processing, 200 GB at $0.045 | $9.00 |
| NAT hourly charge: each $0.045-per-hour unit | $32.85 per unit (two attachments with NAT, possibly per AZ) |
So the NAT feature adds roughly $9 per 200 GB plus at least $65.70 a month in hourly charges for the two translated attachments if the hourly charge is counted per attachment, and more if it is counted per Availability Zone. Compare that with the private-NAT-gateway workaround, which needs a private NAT gateway in each AZ of each VPC: four zonal private NAT gateways at $0.045 per hour is $131.40 a month before any data. For a busy link, data processing dominates, so measure your traffic first with BytesIn on the attachments. Our NAT gateway bill guide explains how NAT data charges build up.
"Seventy-odd dollars a month to avoid renumbering," Jake said. "That's cheaper than one evening of my time." "For now," Ethan said. "We still renumber the booking VPC next year. This buys us the year."
1:1 NAT vs renumbering vs private NAT gateway vs PrivateLink
| Option | Both sides can start connections? | Effort | Best for |
|---|---|---|---|
| Transit Gateway 1:1 NAT | Yes | Rules on attachments; DNS, routes and security groups move to NAT ranges | Mergers, partners over VPN, many services across two overlapping networks |
| Renumbering | Yes | High: every address in every config | Networks you own for the long term |
| Private NAT gateway + secondary CIDR | No, outbound only | Medium: extra CIDR, subnets, gateways per AZ | One-way access, or regions or partitions without 1:1 NAT |
| PrivateLink | Consumer to provider only | Low per service | Exposing a few specific services |
| NAT appliance | Yes | High: you run, patch and scale it | Port translation or features 1:1 NAT lacks |
PrivateLink pricing is in our VPC endpoint pricing guide. A sensible pattern for an acquisition: 1:1 NAT on day one so the businesses can work together, then renumber the smaller network on a calm timetable, then remove the rules.
A migration plan for a live network
When one of the overlapping networks is already in use, the route swap is the risk. This order keeps the outage to the change window itself:
- Inventory. List every CIDR in your VPCs (primary and secondary), offices, partners and other clouds. Run the plan checker against it.
- Prepare the peers. Add routes for the NAT ranges in every VPC route table that will use them, add security group and network ACL rules for the NAT ranges, and create the DNS records that point to NAT addresses. None of this changes traffic yet.
- Tell the partners. Anyone with an allowlist for your real addresses needs the NAT range, and anyone advertising routes over BGP needs to know which mode you chose.
- Enable NAT in a maintenance window, on both overlapping attachments, then wait until both show
enabledand every ruleactivated. - Switch the clients to the NAT addresses (or flip the DNS records), and only then remove old rules for real addresses.
- Watch
PacketsOutNAT,PacketDropCountBlackholeandPacketDropCountNoRoutefor the first day.
To back out, disable NAT on the attachment. The rules are kept in the deactivated state and come back as activated if you enable it again, so a rollback does not lose your work:
aws ec2 modify-transit-gateway-attachment-nat-configuration \
--transit-gateway-attachment-id tgw-attach-0aaaaaaaaaaaaaaaa \
--nat-gateway-support disable
To clear the rules completely, add --reset-nat-gateway-rules to the same command. NAT cannot stay enabled with zero rules, which is why the disable goes in the same call.
A five-minute test after you enable it
get-transit-gateway-attachment-nat-configurationon each attachment: supportenabled, every ruleactivated, nothingdeleting.- Search the transit gateway route table for each NAT range: one
systemroute per translated VPC, and no static route for the same prefix pointing somewhere else. - Check the VPC route tables: each side routes the other side's NAT range to the transit gateway.
- From one side, connect to the other side's NAT address on a port its security group allows (
nc -vz 100.65.0.20 443). - On the receiving server, confirm the client appears with its NAT address (for example in the web server's access log).
- Check CloudWatch for non-zero
PacketsInNATandPacketsOutNATon the attachments.
A ping is a weak test here: ICMP can be blocked by security groups that allow TCP, and our ping troubleshooting guide explains why. Test the real port.
Troubleshooting Transit Gateway 1:1 NAT
Requests reach the far side, but replies never come back
Either only one of two overlapping networks is translated (the replies stay local inside the untranslated VPC), or the rule on a VPC is narrower than the VPC CIDR and no route exists for its NAT range. Translate both sides, or add a static transit gateway route for the NAT range that targets the VPC attachment.
Everything that used to reach the VPC by its real address stopped working
That is the route swap: a rule that exactly matches a VPC CIDR replaces the VPC's propagated route with the NAT route. Move those peers to the NAT range, or, if they must keep the real address, translate only the subnets that clash.
The NAT route shows as blackhole
On a BGP VPN or Direct Connect gateway with system routes on, the NAT route is active only while the far side advertises a route that overlaps the original range. Ask the partner to advertise it again, or switch to system routes off and have them advertise the NAT range.
AccessDenied when reading the NAT configuration
The role needs ec2:GetTransitGatewayAttachmentNatConfiguration, which ec2:Describe* does not include, and it must be in the account that owns the transit gateway.
The console will not save, or the CLI refuses a change
Support is still enabling or disabling. Wait for it to settle (the wait script above does this), then retry.
InvalidParameterValue when enabling NAT on a Connect or transport attachment
NAT is already enabled on the partner attachment of that pair. Disable it there, wait for disabled, then enable it where you want it.
Cannot enable NAT on the inspection VPC attachment
Appliance mode is on. Leave the inspection attachment alone and place NAT rules on the spoke attachments instead.
A rule I did not touch disappeared
The rule list replaces the whole set. Someone sent a list without it, from the console form or the CLI. Keep rules in code, in one place, and always send the complete set.
Translated traffic is blocked by the security group
The receiving side sees the NAT address. Allow the sender's NAT range, not its real CIDR.
Overlapping CIDRs and 1:1 NAT: frequently asked questions
Does Transit Gateway support overlapping CIDRs?
Yes, since October 23, 2026, through 1:1 NAT on attachments. Without NAT rules, a newly attached VPC whose CIDR overlaps an existing one is still not propagated.
How do I connect two VPCs with the same CIDR in AWS?
Attach both to a transit gateway and give each attachment a 1:1 NAT rule to its own unique NAT range, for example 100.64.0.0/16 and 100.65.0.0/16. Then route each side's NAT range in the other VPC and update security groups and DNS.
Can I translate only one of the two overlapping VPCs?
No. The untranslated VPC sends replies to an address inside its own CIDR, and its local route keeps them inside the VPC. Translate both.
What is 1:1 NAT in AWS Transit Gateway?
A static, stateless mapping from one CIDR to another of the same size on an attachment. Source addresses are translated outbound, destination addresses are translated back inbound, host bits and ports stay the same.
Which NAT CIDR ranges can I use?
Private RFC 1918 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) or the shared address space 100.64.0.0/10, with the same prefix length as the original CIDR.
How many NAT rules can an attachment have?
Up to 50, with rule numbers from 1 to 32766. Rule numbers are labels, not priorities, because rules on one attachment can never overlap.
Does 1:1 NAT work with Site-to-Site VPN and Direct Connect?
Yes. With BGP, the transit gateway can install the NAT route for you (active while the original range is advertised), or you can advertise the NAT range yourself. Static VPNs need a static route for the NAT range.
Does Transit Gateway 1:1 NAT support IPv6?
No. It translates IPv4 only, and IPv6 traffic passes through untranslated.
How much does Transit Gateway 1:1 NAT cost?
It is billed at Regional NAT gateway rates, an hourly charge plus a per-GB charge ($0.045 per GB for a Regional NAT gateway in US East), on top of the normal $0.05 per attachment-hour and $0.02 per GB Transit Gateway charges.
Is 1:1 NAT available on AWS Cloud WAN?
Yes, through the Network Manager API (UpdateAttachmentNatConfiguration and ListAttachmentNatConfigurations). The enable values are upper case there, and the system-route setting is a true or false value.
Can the account that owns a shared VPC attachment see the NAT rules?
No. Only the account that owns the transit gateway can view or modify NAT configuration, even when the transit gateway is shared through Resource Access Manager.
Does enabling 1:1 NAT cause downtime?
Briefly, possibly. Translation and routes update separately, so traffic to new NAT addresses can drop for a short time. On a VPC, the real-address route is also replaced, so peers using real addresses lose the path until they move to the NAT range.
When should I worry about overlapping CIDR ranges in a multi-account structure?
As soon as two accounts might ever need to talk through a shared transit gateway, VPN or peering. Plan non-overlapping ranges with a central IP plan from the start, and keep 1:1 NAT for the networks you did not number yourself, such as acquisitions and partners.
What architecture should I use for external partners over VPN with overlapping CIDRs and NAT?
Terminate the partner VPN on a transit gateway, put a 1:1 NAT rule on the VPN attachment mapping the partner's range to a dedicated NAT range, and translate your own overlapping VPC too if the ranges clash. The partner then reaches you, and you reach the partner, through NAT ranges only.
Are there any creative solutions for a VPN to multiple accounts with overlapping CIDRs?
Bring every account's VPC onto one shared transit gateway and give each overlapping VPC attachment its own slice of 100.64.0.0/10. The VPN then reaches every account through a unique NAT range, with no appliance in the middle.
How do I set up a VPC to VPC connection with overlapping IP space?
Use a transit gateway with 1:1 NAT on both VPC attachments, each to its own NAT range. VPC peering cannot connect overlapping CIDRs at all, and PrivateLink only fits when one side consumes a specific service.
Is there a workaround for a Site-to-Site VPN CIDR overlap with Direct Connect?
If the VPN and the Direct Connect site advertise overlapping ranges into one transit gateway, add a 1:1 NAT rule to one of those attachments (or both) so each arrives under a unique NAT range, and pick the system-route mode that matches what each site advertises.
What does a CIDR overlaps with an existing subnet error mean?
That is a different problem: inside one VPC, a new subnet's CIDR overlaps an existing subnet (error code InvalidSubnet.Conflict). Pick a free block within the VPC range or add a secondary CIDR. 1:1 NAT does not apply inside a VPC.
For readers preparing for an AWS certification
We have been covering AWS certifications alongside our fixes, so here is a short extra for readers studying for one. If you only came for the fix, you already have it; feel free to skip this part.
Exams that test this topic: Solutions Architect – Associate (SAA-C03) • Solutions Architect – Professional (SAP-C03 from November 17, 2026) • CloudOps Engineer – Associate (SOA-C03).
Here are the exam-style questions this topic tends to raise, with the reasoning you need to answer them:
1. A company acquired another business. Both companies use VPCs with the CIDR 10.0.0.0/16, and the VPCs must communicate in both directions through an existing transit gateway without renumbering. What is the most operationally efficient solution?
Enable 1:1 NAT on both VPC attachments of the transit gateway, mapping each VPC to its own unique NAT CIDR, and route each NAT CIDR to the transit gateway in the other VPC's route tables.
2. A NAT rule was added on only one of two transit gateway VPC attachments whose CIDRs are identical. Requests reach the far side, but responses never return. Why?
The untranslated VPC sends replies to an address inside its own CIDR, which the VPC delivers locally. Each overlapping VPC needs its own NAT CIDR.
3. A partner connects over AWS Site-to-Site VPN from an address range that overlaps a VPC. The partner must reach an application only through addresses the company chooses. Which design meets this?
Terminate the VPN on a transit gateway and add a 1:1 NAT rule on the VPN attachment that maps the partner's range to a dedicated NAT CIDR, translating the overlapping VPC as well.
4. Which option cannot connect two VPCs whose CIDR blocks overlap?
VPC peering, which does not support overlapping CIDRs. A transit gateway with 1:1 NAT, AWS PrivateLink for specific services, or private NAT gateways can.
5. Many consumer VPCs with overlapping CIDRs must call a single application in a provider VPC. Only consumer-initiated connections are needed. Which solution is simplest?
AWS PrivateLink: an endpoint service behind a Network Load Balancer, with interface endpoints in each consumer VPC, which works regardless of overlapping CIDRs.
6. An operations engineer needs an alarm when a transit gateway drops traffic because a route has become a blackhole. Which CloudWatch metric should be used?
PacketDropCountBlackhole (or BytesDropCountBlackhole) in the AWS/TransitGateway namespace, with the TransitGateway or TransitGatewayAttachment dimension, using the Sum statistic.
Exam codes and dates change often. Our AWS certification changes page keeps track of what is current.
On Sunday night, Ethan saved four rules, two per side, and watched both attachments go from enabling to enabled. The booking app found the inventory app at a 100.64 address it had never seen before, and the tills were back on their new NAT addresses before the first one rang on Monday. "Nobody noticed," Jake said. "That's the whole job," Ethan said. If your setup behaves differently from what this page describes, please tell us. Guides like this stay right because readers write in.
📌 If you keep one line from this page
When two networks overlap, give each its own NAT range, because one-sided NAT sends the replies home to the wrong VPC, and move every peer to the NAT addresses before you save, because the real-address route disappears.
Both sides translated · same prefix length · RFC 1918 or 100.64.0.0/10 · 50 rules · IPv4 only · owner account only · October 24, 2026.
Revision note. Written October 24, 2026, the day after AWS added 1:1 NAT to Transit Gateway and Cloud WAN. "Measure twice, cut once," the old carpenters' saying goes, and with NAT ranges the measuring is the CIDR inventory.