About this article: AI-assisted writing, reviewed against the cited sources. This is source research, not a lab validation of the procedures. Check the stated versions and your own recovery requirements before making changes.
Use BGP if your customer gateway device supports it. AWS recommends it because BGP's liveness checks help failover to the second tunnel. It is also the only routing type that supports equal-cost multipath (ECMP) on a transit gateway.
Whichever you choose, expect asymmetry. AWS states that traffic towards AWS uses both tunnels, while traffic from AWS prefers one. A device that needs both directions of a flow on the same tunnel can drop traffic unless you design for it.
Commands below come from the AWS references, except where marked as written for this article. None was run in a lab.
Why it matters
Three faults look like broken networking but are normal behaviour of this design:
- Both tunnels show UP, yet replies vanish because the return path is on the other tunnel.
- AWS maintenance on one tunnel causes an outage, because the device was pinned to that tunnel.
- A routine prefix addition takes BGP down, because a route quota was crossed.
Each one can be identified from data AWS already publishes, before anyone changes a tunnel.
How the two tunnels carry traffic
Every connection has two tunnels, each with its own public IP address and each ending in a different Availability Zone. The AWS end is either a virtual private gateway (one VPC) or a transit gateway (a hub for many). That choice sets the limits below.
| Property | Virtual private gateway | Transit gateway |
|---|---|---|
| Tunnels AWS sends on | One tunnel across all connections on the gateway | Several, with ECMP and dynamic routing |
| Routes received from your device | 100 | 1,000 |
| Routes sent to your device | 1,000 | 5,000 |
| Where static routes live | On the VPN connection, up to 100 | In the transit gateway route table |
| Bandwidth per tunnel | Up to 1.25 Gbps | Up to 1.25 Gbps, or 5 Gbps with Large Bandwidth Tunnels |
| IPv6 | Not supported | Supported |
| Acceleration | Not supported | Supported, but not with Large Bandwidth Tunnels |
None of those route or bandwidth quotas can be raised. A standard tunnel is limited to 140,000 packets per second and a Large Bandwidth Tunnel to 400,000.
Large Bandwidth Tunnels are unavailable in some Regions, including Melbourne (ap-southeast-4), and both tunnels of a connection must use the same setting.
BGP against static routing
| Question | BGP (dynamic) | Static |
|---|---|---|
| How AWS learns your networks | Your device advertises them | You enter the prefixes |
| Liveness | BGP checks, plus dead peer detection | Your device's own health checks, plus dead peer detection |
| ECMP on a transit gateway | Yes | No |
| Influence over the tunnel AWS uses | AS path and more specific prefixes | None documented |
| Finding AWS's preferred tunnel | The MED value | Traffic statistics or metrics |
MED, the multi-exit discriminator, is a BGP attribute that tells a neighbour which entry point to prefer. Lower wins.
A connection is one type or the other: with BGP selected, you cannot specify static routes. The modify-vpn-connection-options synopsis has no routing-type parameter, so the inference is that the type is fixed at creation. Check the current API before planning around that.
The type is set when the connection is created:
aws ec2 create-vpn-connection \
--type ipsec.1 \
--customer-gateway-id cgw-0abc1234def567890 \
--vpn-gateway-id vgw-1a1a1a1a1a1a2b2b2 \
--options "{\"StaticRoutesOnly\":true}"
Omit --options for a dynamic connection. On a virtual private gateway, static prefixes are added one at a time:
aws ec2 create-vpn-connection-route \
--vpn-connection-id vpn-40f41529 \
--destination-cidr-block 10.20.0.0/16
How AWS chooses a route
Tunnel endpoint health takes precedence over other routing attributes, on both gateway types. Among healthy endpoints, the longest prefix wins. For identical prefixes on a virtual private gateway, the order is:
- BGP routes from Direct Connect.
- Static routes added to a VPN connection.
- BGP routes from a VPN connection, shortest AS path first.
- Between equal AS paths whose first AS matches, the lowest MED.
The VPC route table sits in front of all of this. The local route wins, even against a more specific propagated route. A static route with an identical destination beats a propagated one, so an old route to an internet gateway can silently take traffic away from the VPN.
The subnet route table needs a route to the gateway, or propagation:
aws ec2 enable-vgw-route-propagation \
--route-table-id rtb-22574640 \
--gateway-id vgw-9a4cacf3
On a transit gateway, a static route to a VPN attachment is not filtered by Site-to-Site VPN. AWS warns that this might allow unintended outbound traffic when the VPN uses BGP.
Failover: what it depends on
AWS publishes no failover time in the pages checked for this article. The duration depends on which of these detects the fault first.
Dead peer detection (DPD). The default timeout is 40 seconds, the minimum is 30. The default action, Clear, stops the tunnel and clears its routes. Restart restarts the IKE session and None takes no action.
BGP hold timer. RFC 4271 has each side use the smaller of its own and its peer's hold time, and suggests keepalives at no more than one third of it. AWS's Check Point example sets a hold time of 30 and a keepalive of 10. Your device's vendor documentation decides what is valid there.
Static routing. AWS says only that devices without BGP may perform health checks to assist failover. If yours does not, the inference is that it may keep sending into a dead tunnel.
Idle tunnels. Without IKE initiation from the AWS side, a period of idle time, usually 10 seconds, might take the tunnel down. AWS suggests keepalive pings. A startup action of Start makes AWS initiate, for IKEv2 only.
Planned replacement of a tunnel endpoint
AWS updates one tunnel of a connection at a time, and redundancy is briefly lost while it does. During the update AWS sets a lower outbound MED on the other tunnel.
That only works if your device listens. Weight and Local Preference rank above MED, so AWS tells you to keep them equal on both tunnels for the lower MED to take effect.
Your own changes also replace endpoints:
| Change | API action | Impact |
|---|---|---|
| Target gateway or customer gateway | ModifyVpnConnection |
Both tunnels unavailable while new endpoints are provisioned |
| VPN connection options | ModifyVpnConnectionOptions |
Both tunnels unavailable |
| Tunnel options | ModifyVpnTunnelOptions |
The modified tunnel, for up to several minutes |
If you cannot tolerate surprise maintenance, tunnel endpoint lifecycle control lets you accept updates at a chosen time before an auto-apply date. AWS notes that it might still apply critical updates immediately in rare circumstances. Pending state is visible with this command, written for this article from the CLI synopsis:
aws ec2 get-vpn-tunnel-replacement-status \
--vpn-connection-id vpn-12345678901234567 \
--vpn-tunnel-outside-ip-address 203.0.113.17
If one tunnel is down for more than an hour in a day, AWS sends a monthly single-tunnel notification through the Health Dashboard. It is a monthly summary, not an alert.
Device failure
Two tunnels do not protect you from losing the on-premises device. AWS's answer is a second connection with a second customer gateway, with both devices advertising the same ranges. The customer gateway IP for the second connection must be publicly accessible.
Asymmetric return traffic
AWS selects one tunnel as the primary egress path and says the selection may change. Your device sends on whichever tunnels its own routing selects. So a request can leave on tunnel 1 and its reply can arrive on tunnel 2.
A router forwarding by destination does not care. A stateful firewall that tracks a session per interface or zone may see a reply with no matching session, and drop it. That is an inference from how such firewalls work, so confirm it in your vendor's documentation.
There are two designs.
Allow asymmetry (AWS's preference). AWS strongly recommends devices that support asymmetric routing and, for those devices, recommends against AS path prepending, so both tunnels keep equal AS paths and MED can do its job during updates.
Pin one tunnel (only if the device cannot do asymmetry). AWS allows AS path prepending and Local Preference to favour one tunnel, and warns that traffic may drop when the egress path changes.
| Control on your device | Direction it influences | Consequence |
|---|---|---|
| Local Preference or Weight | Your traffic towards AWS | Outranks AWS's MED signal during maintenance |
| AS path prepending on the standby tunnel | AWS's traffic towards you | AWS advises against it where asymmetry is supported, so that MED decides tunnel priority during updates |
| More specific prefixes | AWS's traffic towards you | AWS's recommended lever, and counts against the route quota |
Pinning does not remove the failure mode. It moves it to the moment the path changes, so treat that as a risk to monitor.
With ECMP on a transit gateway, several tunnels carry traffic in both directions, so the inference is that per-flow symmetry should not be assumed. VpnEcmpSupport is enabled by default on new transit gateways. AWS's example reaches 20 Gbps with two Large Bandwidth connections across four tunnels.
Proving which tunnel carries what
AWS's troubleshooting order is IKE, IPsec, tunnel, then BGP. The static version ends with static routes instead. Stop at the first layer that fails.
The firewall in front of the device must allow UDP 500 and IP protocol 50 (ESP) to and from both outside addresses, plus UDP 4500 with NAT traversal.
Step 1: read tunnel state. This --query was written for this article:
aws ec2 describe-vpn-connections \
--vpn-connection-ids vpn-0123456789abcdef0 \
--query 'VpnConnections[].{Static:Options.StaticRoutesOnly,Routes:Routes,Tunnels:VgwTelemetry[].{Ip:OutsideIpAddress,Status:Status,Accepted:AcceptedRouteCount,Changed:LastStatusChange,Message:StatusMessage}}'
LastStatusChange moves when IKE, IPsec or BGP status changes. On a BGP connection, compare AcceptedRouteCount between tunnels. As an editorial check, a tunnel reporting UP with far fewer accepted routes than its partner points to what the device advertises on that tunnel.
Step 2: measure each direction per tunnel. This command was written for this article from the get-metric-statistics reference:
aws cloudwatch get-metric-statistics \
--namespace AWS/VPN \
--metric-name TunnelDataOut \
--dimensions Name=TunnelIpAddress,Value=203.0.113.17 \
--start-time 2026-11-10T00:00:00Z \
--end-time 2026-11-10T01:00:00Z \
--period 300 \
--statistics Sum
TunnelDataOut is what AWS sends to you, and TunnelDataIn is what AWS receives from you. Run both for both tunnel addresses. Most TunnelDataOut on tunnel 2 alongside most TunnelDataIn on tunnel 1 indicates asymmetric paths (an inference from the metric definitions). Small byte counts prove nothing, since AWS notes these metrics can report usage even on a down tunnel because of status checks and background requests.
TunnelState per VpnId falls between 0 and 1 when at least one tunnel is not up. For BGP connections, 1 means ESTABLISHED, so it reflects the BGP session, not only IPsec. That value is the alarm to set.
Step 3: read the logs. Tunnel activity and BGP logs go to CloudWatch Logs, and record DPD events and each BGP transition.
Warning: Enabling logs on an existing tunnel can interrupt it for several minutes. Do one tunnel at a time, with the other confirmed up.
| Log text | What it proves |
|---|---|
Peer is not responsive - Declaring peer dead (IKEv1), AWS tunnel DPD timed out (IKEv2) |
DPD fired |
session state has changed from Connect to Active |
One such line proves little. If the session stays in Connect, check TCP 179 on the customer gateway |
maximum prefix limit was exceeded |
Too many prefixes; the session goes down |
notification 6/1 (Cease/Maximum Number of Prefixes Reached) |
The BGP session was terminated for that reason |
DENIED due to: as-path contains our own AS |
Your advertisement carries the AWS-side AS |
DENIED due to: non-connected next-hop |
The advertised next hop failed validation |
The prefix-limit row is the one that surprises people. A site advertising 120 prefixes to a virtual private gateway (a hypothetical example) is past the 100-route quota. Summarise the prefixes rather than adding more. Both tunnels normally advertise the same routes, so the inference is that both sessions are exposed at once.
Step 4: rule out packet size. AWS supports an MTU of 1446 and MSS of 1406 at most, lower with some algorithms, and Path MTU Discovery is not supported.
| Encryption | Integrity | NAT traversal | MTU | MSS (IPv4) |
|---|---|---|---|---|
| AES-GCM-16 | N/A | Off | 1446 | 1406 |
| AES-GCM-16 | N/A | On | 1438 | 1398 |
| AES-CBC | SHA-1 or SHA2-256 | Off | 1438 | 1398 |
| AES-CBC | SHA-1 or SHA2-256 | On | 1422 | 1382 |
| AES-CBC | SHA2-384 | Off or On | 1422 | 1382 |
| AES-CBC | SHA2-512 | Off | 1422 | 1382 |
| AES-CBC | SHA2-512 | On | 1406 | 1366 |
AWS's pages are not uniform here. The device requirements page gives a 1399-byte interface MTU for dynamically routed connections. The editorial recommendation is to use the algorithm table above and clamp MSS to match.
Planning a failover rehearsal
A tunnel shutdown interrupts traffic and is not a diagnostic command. The exact customer-gateway procedure must come from its vendor and be reviewed and rehearsed on an isolated connection. A production exercise needs a separately approved window, a confirmed healthy second tunnel and an independent management path. No shutdown runbook was validated for this article.
The test plan should record VgwTelemetry and per-tunnel metrics beforehand, use both a continuous reachability probe and a long-lived TCP session, and define recovery criteria before any interruption. Measure the start and end of loss, whether the TCP session survives, and whether TunnelDataIn and TunnelDataOut confirm the expected traffic movement. Include restoration of the original routing state and a stable observation period.
Cover both tunnel-failure cases individually: testing one leaves half the design unproven. A controlled session failure does not prove resilience to every device, link or application failure.
What to choose and why
These are editorial recommendations.
Use BGP unless the device cannot. You gain route withdrawal, MED signalling during maintenance and access to ECMP. Static is reasonable for a device with no BGP and only a few stable prefixes, provided it has a working health check.
Prefer a transit gateway if prefix count is near 100 or you need ECMP. The route quotas are fixed, so growth cannot be solved with a quota request.
Allow asymmetry on the firewall where the product supports it, then leave Weight and Local Preference equal so AWS's MED signal works.
Add a second connection and device if the site must survive a device failure. AWS's Ohio pricing example shows USD 0.05 per connection-hour, plus data transfer. Check your Region before budgeting.
Keep both tunnels up and monitored. An alarm on TunnelState below 1 finds the lost redundancy before the next maintenance event does.
Risks and limits
- AWS says its egress tunnel selection may change at times. Do not build on the assumption that it stays put.
- Local Preference and prepending can defeat AWS's maintenance signal.
- Route quotas are not adjustable, and exceeding the prefix limit terminates the BGP session.
- The minimum DPD timeout is 30 seconds, so sub-second failover is not available from DPD.
- Modifying tunnel or connection options interrupts service, as does enabling logs on an existing tunnel.
- Jumbo frames and Path MTU Discovery are not supported. Fragment before encryption where the device allows it, as AWS recommends.
- Quotas and Region lists change. Everything here reflects the pages as checked on 2026-11-10.
Sources
Opened 2026-11-10. Sources behind the corrections reopened 10 November 2026.
- Tunnel options
- Configure tunnel options
- Route tables and route priority
- Static and dynamic routing
- Routing during tunnel endpoint updates
- Tunnel endpoint replacements
- Tunnel endpoint lifecycle control
- Redundant connections
- Quotas
- Customer gateway best practices
- Customer gateway requirements
- Firewall rules
- CloudWatch metrics
- Site-to-Site VPN logs
- Troubleshooting with BGP
- Troubleshooting without BGP
- VPN attachments in Transit Gateway
- AWS VPN pricing
- RFC 4271: BGP-4
- AWS CLI EC2 command reference
This article was originally published on .