This check flags AWS internet gateways that exist but aren't attached to any VPC. They do nothing useful, clutter your account, and may be leftovers from sloppy teardown. Detach and delete the orphaned gateway, or attach it to the VPC that needs it.
Internet gateways are one of those AWS resources you create once, wire up, and forget about. They sit quietly at the edge of a VPC, routing traffic between your public subnets and the internet. But when a VPC gets deleted, or when someone provisions a gateway during testing and never finishes the job, you can end up with an internet gateway floating in your account attached to nothing at all.
The vpc_unusedigw check catches exactly that: an internet gateway (IGW) that is not associated with any VPC. On its own it's not a screaming security hole, but it's a strong signal that something went wrong in your provisioning or cleanup process, and orphaned resources have a habit of becoming the place where bad assumptions live.
What this check detects
An AWS internet gateway can be in one of two states: attached to a VPC, or detached. When attached, it provides a route for resources in public subnets to reach the public internet and for inbound traffic to reach those resources. When detached, it routes nothing. It just exists.
The vpc_unusedigw check looks at every internet gateway in a region and reports any that have no VPC attachment. In the AWS API, an attached gateway has an entry in its Attachments array with a State of available or attached. A flagged gateway has an empty Attachments list.
Note: An internet gateway can only be attached to one VPC at a time, and a VPC can only have one internet gateway. So a detached IGW is never "shared" capacity waiting to be used. It is genuinely idle.
Why it matters
Internet gateways themselves are free, so this isn't a cost problem in the direct sense. The risk is operational and security hygiene related.
It signals incomplete teardown
The most common way you end up with an orphaned IGW is a half-finished cleanup. Someone deleted a VPC's resources, detached the gateway to unblock the VPC deletion, and then never came back to delete the gateway. If that happened, there's a good chance other resources from the same environment are also lingering: unused Elastic IPs (which do cost money), stale security groups, orphaned NAT gateways, or dangling route tables.
It eats into account limits
AWS enforces a default limit of five internet gateways per region. That sounds generous until a CI pipeline that spins up ephemeral VPCs starts leaking gateways. Once you hit the limit, new VPC deployments that need an IGW fail, and the error message ("InternetGatewayLimitExceeded") rarely points engineers at the dead gateways causing it.
Warning: If automated infrastructure deployments suddenly start failing with gateway limit errors, check for orphaned IGWs before requesting a limit increase. Raising the limit just hides the leak and lets it grow.
It widens the audit surface
Every resource in your account is something a security reviewer has to account for. A detached gateway with no clear owner or tags forces someone to ask: "Is this safe to delete, or is it about to be attached to something?" Multiply that across hundreds of accounts and the unanswered questions pile up. Clean accounts are auditable accounts.
How to fix it
You have two paths. If the gateway is genuinely abandoned, delete it. If it was meant to serve a VPC that's still running without internet access, attach it. Start by confirming the state.
Step 1: Find the orphaned gateways
aws ec2 describe-internet-gateways \
--filters "Name=attachment.state,Values=available" \
--query 'InternetGateways[?length(Attachments)==`0`].[InternetGatewayId,Tags]' \
--output table
A cleaner way to list every gateway with no attachment at all:
aws ec2 describe-internet-gateways \
--query 'InternetGateways[?length(Attachments)==`0`].InternetGatewayId' \
--output text
Step 2: Decide attach or delete
Check the tags and creation context. If the gateway has a tag pointing at an active project or VPC, find out whether that VPC needs internet access. If it's untagged and nothing references it, it's a deletion candidate.
Step 3a: Attach it (if a VPC needs it)
aws ec2 attach-internet-gateway \
--internet-gateway-id igw-0abc123def456 \
--vpc-id vpc-0987654321fedcba
Remember that attaching the gateway is only half the job. You still need a route in the relevant route table pointing 0.0.0.0/0 at the gateway for traffic to flow:
aws ec2 create-route \
--route-table-id rtb-0123456789abcdef0 \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id igw-0abc123def456
Step 3b: Delete it (if it's abandoned)
Danger: Deleting an internet gateway is permanent. Confirm the gateway has zero attachments and is not referenced by any IaC state before you run this. If it turns out a VPC was supposed to use it, recreating and reattaching is straightforward, but any hardcoded gateway ID in route tables or templates will break.
A detached gateway can be deleted directly. If it were still attached, you'd need to detach first.
# Detach only if it still has an attachment
aws ec2 detach-internet-gateway \
--internet-gateway-id igw-0abc123def456 \
--vpc-id vpc-0987654321fedcba
# Delete the orphaned gateway
aws ec2 delete-internet-gateway \
--internet-gateway-id igw-0abc123def456
Doing it in the console
- Open the VPC console and select Internet gateways in the left navigation.
- Sort or filter by the State column and look for any showing
Detached. - Select the detached gateway, review its tags, then choose Actions → Delete internet gateway.
- Type
deletein the confirmation field and confirm.
Tip: Before bulk-deleting, dump the gateway IDs and tags to a file so you have a record of what was removed and when. aws ec2 describe-internet-gateways --output json > igw-backup-$(date +%F).json gives you a snapshot to reference if anyone asks later.
How to prevent it from happening again
Orphaned gateways are almost always a symptom of resources being managed outside of infrastructure as code, or of IaC stacks being torn down out of order. The fix is to make creation and deletion atomic.
Manage gateways with IaC, always together with the VPC
When the gateway and its attachment live in the same Terraform module or CloudFormation stack, you can't end up with one without the other. Destroying the stack removes both.
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "app-prod"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "app-prod-igw"
ManagedBy = "terraform"
}
}
Because the aws_internet_gateway references aws_vpc.main.id, Terraform knows the dependency order. On terraform destroy it detaches and deletes the gateway before removing the VPC, leaving nothing behind.
Gate it in CI/CD with policy-as-code
You can catch IGWs that aren't tied to a VPC during the plan stage. Here's an OPA/Rego style check you can run against a Terraform plan in your pipeline:
package terraform.igw
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_internet_gateway"
not resource.change.after.vpc_id
msg := sprintf("Internet gateway %s has no vpc_id and will be orphaned", [resource.address])
}
Sweep for leaks on a schedule
For anything created outside IaC, a scheduled job that flags detached gateways closes the gap. A simple Lambda on a daily EventBridge schedule running the describe call from earlier, then publishing to SNS, gives you a same-day alert instead of a surprise during your next audit.
Tip: Lensix runs the vpc_unusedigw check continuously across every connected AWS account and region, so you get a single view of orphaned gateways without standing up your own Lambda and SNS plumbing.
Best practices
- Tag every gateway at creation with an owner, environment, and the managing team or pipeline. An orphaned but well-tagged gateway is trivial to triage. An untagged one becomes a mystery nobody wants to delete.
- Tear down stacks in the right order. If you're scripting cleanup manually, detach and delete the gateway before deleting the VPC, never the other way around. Better still, let IaC handle the ordering.
- Treat the per-region limit as a leak detector. If you're approaching five gateways in a region, audit before assuming you need more. The same advice applies to Elastic IPs and NAT gateways.
- Pair this check with related VPC hygiene checks. Orphaned gateways rarely appear alone. Look for unused security groups, unattached Elastic IPs, and empty route tables in the same environment.
- Run cleanup in lower environments first. Dev and staging accounts accumulate orphaned resources fastest because they churn the most. Fixing the leak there often reveals the IaC gap before it ever reaches production.
A detached internet gateway is a small thing, but it's the kind of small thing that tells you how disciplined your provisioning lifecycle really is. Clean it up, then close the loop in your pipeline so the same gateway never has to be cleaned up twice.

