Appliance mode has a prerequisite that silently undoes it
Enable appliance mode and forget route propagation on the associated Transit Gateway route table, and every flow falls back to hash-based Availability Zone selection. The attachment still reports appliance mode enabled.
· Venerable Networks
Appliance mode exists because Transit Gateway's default behaviour breaks stateful inspection. Without it, the two directions of a flow can be handed to appliances in different Availability Zones, and a firewall that only sees half a conversation drops it.
So you enable appliance_mode_support on the inspection VPC's attachment and move on. There is a prerequisite, and missing it puts you back where you started while the console still says appliance mode is enabled.
From the Transit Gateway VPC attachment documentation:
Route propagation must be enabled for the transit gateway route table associated with the appliance-mode VPC attachment. Without propagation, the transit gateway cannot determine the source and destination Availability Zones. All traffic — including the same-Availability-Zone flows — falls back to flow-hash-based Availability Zone selection. This means traffic within the same Availability Zone might be routed to a different Availability Zone in the appliance VPC, breaking Availability Zone isolation.
Why propagation is load-bearing here
Appliance mode is not just flow stickiness. It is Availability-Zone-aware routing, and the Transit Gateway needs to know which zone the source and destination are in to do it.
That information comes from propagated routes. Propagation is how the Transit Gateway learns the CIDRs behind an attachment and, with them, the zone structure. Strip propagation from the route table associated with the appliance attachment and the Transit Gateway loses the input it reasons over, so it does the only thing left: hashes the flow and picks a zone.
The flow is still consistent for its lifetime — that part of appliance mode survives — but the zone chosen has nothing to do with where the traffic came from or is going.
The four documented cases
Worth knowing individually, because only one of them is the case people test:
Same-zone source and destination. With propagation, the Transit Gateway picks the appliance ENI in that zone and holds it for the flow. This is the scenario everybody tests, and it is the one that silently changes when propagation is missing.
Cross-zone source and destination. A flow hash picks one of the appliance zones and sticks with it. Expected behaviour, propagation or not.
Destination with no zone information, such as internet-bound traffic. The Transit Gateway uses the source's zone.
Appliance in zones distinct from both source and destination. Flow hash again, consistently for the flow.
So with propagation missing, cases one and three degrade into case two. Nothing errors. Traffic keeps flowing. What you lose is the zone isolation you built the architecture around.
Why it is hard to notice
The attachment reports appliance mode enabled, because it is. The setting is real and it is doing what it can with the information available.
Nothing alarms. Inspection still works — packets reach an appliance and both directions of a flow reach the same appliance, so a stateful firewall does not break. What breaks is the assumption that same-zone traffic stays in-zone.
The consequences are cost and blast radius rather than errors. Cross-zone data transfer charges appear where you did not expect them. And a zone failure now affects flows that should have been unaffected, which is the kind of thing you discover during the zone failure.
Two other things worth knowing about appliance mode
It only works on VPC attachments. The documentation is explicit. The flows themselves can originate from any attachment type — VPC, VPN, or Connect — and can cross Regions, but the attachment you enable the setting on has to be a VPC attachment. Teams occasionally try to enable it on a VPN attachment and find the argument does not exist.
Enabling it later rebalances existing flows. From the same page: flows can be rebalanced across Availability Zones if you enable appliance mode after the fact rather than at attachment creation. So turning it on is not a no-op on a live path — existing connections may move, and a stateful appliance will drop the ones that land somewhere new. Enable it during a window, or accept the reset.
Tested, and the documentation is incomplete
The statement above is necessary but not sufficient, which I found by building it.
Setup: a transit gateway, two spoke VPCs both in us-east-2a, and an appliance VPC with a
subnet and an instance in us-east-2a and us-east-2b. Appliance mode enabled on the appliance
attachment, which spans both zones. Sixty distinct TCP flows opened from the spoke client and captured
on both appliance instances, counting which one received each. The tables below count the flows that
completed — 53, 53 and 52 across the three runs — rather than all sixty probes.
Source and destination are in the same zone, so documented Scenario 1 applies: with the prerequisite
satisfied, every flow should land on the us-east-2a appliance.
| Propagation on the appliance route table | Static routes to the spokes | AZ-a appliance | AZ-b appliance |
|---|---|---|---|
| none | present | 29 flows | 24 flows |
| enabled | present | 24 flows | 29 flows |
| enabled | removed | 52 flows | 0 flows |
Row two is the finding. Propagation was enabled, get-transit-gateway-route-table-propagations
reported enabled for both spoke attachments, and the behaviour was still flow-hash.
The reason is route precedence. A static route shadows a propagated route at the same prefix. So the route actually being used was static, and a static route carries no Availability Zone information. The transit gateway still could not determine the zones, so it hashed — exactly as if propagation had never been enabled.
Remove the static routes, leave the propagated ones as the only routes, and affinity is perfect. Not approximately: 52 of 52 on the correct zone, zero on the other.
So the accurate prerequisite is stronger than the documented one:
Route propagation must be enabled for the transit gateway route table associated with the appliance-mode VPC attachment, and the propagated routes must be the routes in use. A static route for the same prefix silently restores flow-hash behaviour.
Two details worth carrying from the same runs. Flows were consistent for their lifetime in every phase — the port sets on the two appliances were completely disjoint — so appliance mode's flow stickiness works regardless of propagation. It is only the zone choice that degrades. And the split in the hashing phases was close to even, which means roughly half of same-zone traffic was crossing zones unnecessarily, paying cross-zone data transfer for it.
Row two of the table, drawn. Source and destination are both in us-east-2a, so documented Scenario 1 applies and every flow should land on the us-east-2a appliance. Propagation was enabled and the API confirmed it, but a static route existed for the same prefix, and a static route shadows a propagated one. Static routes carry no Availability Zone information, so the transit gateway had nothing to reason over and hashed: 24 flows to the correct zone, 29 into a zone neither endpoint occupies. Remove the static routes and the same setup gives 52 and 0.
What to check
This is the part the documentation will not tell you to do. Checking propagation is not enough, because propagation can be enabled and shadowed. Check the Type of the route that is actually active:
aws ec2 search-transit-gateway-routes \
--transit-gateway-route-table-id "$APPLIANCE_RTB" \
--filters "Name=state,Values=active" \
--query 'Routes[].[DestinationCidrBlock,Type,State]' --output tableAny row showing static for a prefix you expected to be learned is a prefix with no zone
information attached, and appliance mode is degraded for traffic to it. propagated is what you
want to see.
Then the two calls you would have made anyway. First, is appliance mode actually on:
aws ec2 describe-transit-gateway-vpc-attachments \
--query 'TransitGatewayVpcAttachments[].[TransitGatewayAttachmentId,Options.ApplianceModeSupport]' \
--output tableThen, for the appliance attachment, find its associated route table and confirm that table has propagations:
RTB=$(aws ec2 describe-transit-gateway-vpc-attachments \
--transit-gateway-attachment-ids "$ATTACH" \
--query 'TransitGatewayVpcAttachments[0].Association.TransitGatewayRouteTableId' --output text)
aws ec2 get-transit-gateway-route-table-propagations \
--transit-gateway-route-table-id "$RTB" \
--query 'TransitGatewayRouteTablePropagations[].[TransitGatewayAttachmentId,State]' --output tableAn empty result there means appliance mode is nominally enabled and functionally degraded.
That combination is worth an explicit assertion in whatever checks your network configuration, because it is a state that looks correct from every angle except the one that matters — and per the tests above, "propagation enabled" is itself one of the angles that can look correct while the behaviour is wrong.
The broader pattern
This is the third distinct place where a Transit Gateway feature depends on propagation rather than association, and the general shape is worth carrying: association decides which table governs an attachment's outbound traffic; propagation is how the Transit Gateway learns about a network at all. Features that need to reason about topology need propagation, not just a route.
The Transit Gateway routing guide covers appliance mode alongside the association and propagation model, and the propagation gap lab is the same distinction producing a plain outage instead of a silent degradation.