Lab 05: The Hostname That Existed In Only One VPC
A peered VPC cannot resolve an internal service name. The peering is active, routes exist both ways, security groups permit the port, and connecting by IP address works perfectly. The record is present and correct in the private hosted zone.
- Debugging time
- ~30 min
- Reading time
- 11 min
- Reported by
- Data Platform
- Tier
- Specialty
Reporting service cannot resolve db.svc.internal after migration to its own VPC
Reported by Data Platform
The reporting service moved out of the shared VPC into its own account-level VPC last night.
Everything about the move looked clean. The VPC peering connection is active, routes were added in
both directions, and the database security group already permits the new CIDR on 5432.
The service will not start. It fails at connection setup with a name resolution error, not a timeout — so it never gets as far as the network. A developer confirmed she can reach the database by IP address from the new VPC without any problem.
Nobody has changed the hosted zone. The record is there; she checked it in the console.
What you are working with
Two VPCs, peered, in a single Availability Zone.
- EC2
Reporting host (app VPC)
10.30.1.x — resolving db.svc.internal
- RTB
Route 53 Resolver, app VPC
10.30.0.2 — answers for zones associated with THIS VPC
Dropped — svc.internal is not associated with the app VPC, so the Resolver has no record to return and falls through to public DNS, which has no .internal
- GW
VPC peering
active, routed both ways — never reached
- DEST
Database host (data VPC)
10.31.1.x:5432 — listening and reachable by IP
The failure happens at the first hop, before any packet is addressed to the database. Everything downstream is healthy, which is why every network-level check passes.
| Resource | Configuration |
| --- | --- |
| App VPC | 10.30.0.0/16, DNS support and hostnames both enabled |
| Data VPC | 10.31.0.0/16, DNS support and hostnames both enabled |
| Peering | active, 10.31.0.0/16 routed from app, 10.30.0.0/16 routed from data |
| Private hosted zone | svc.internal, containing db.svc.internal → 10.31.1.x |
| sg-data | Inbound 5432 from 10.30.0.0/16 |
| sg-app | All outbound |
Both instances sit in public subnets with an internet gateway, purely so dig and nc install at
launch. That has no bearing on the failure.
Scope and constraints
- In scope: DNS resolution from the application VPC.
- Out of scope: the database itself, the peering connection, security groups, and route tables. All four are correctly configured and you should be able to prove it quickly.
enable_dns_supportandenable_dns_hostnamesare on for both VPCs. This is not that bug.- The record exists and its value is correct. This is not a missing-record bug.
- Reaching for a Route 53 Resolver endpoint is the expensive wrong answer here. Part of the exercise is being able to say why.
Deploy the broken state
cd lab-05-private-zone-association
terraform init
terraform apply
# Shell on the reporting host
aws ssm start-session --target "$(terraform output -raw app_instance_id)"
# The values you will need
terraform output service_fqdn
terraform output data_private_ip
terraform output app_vpc_id
terraform output hosted_zone_idAllow a minute after apply for user_data to install the tooling and start the listener.
Set the values from the outputs above, rather than copying the sample addresses — EC2 assigns the private IPs and they will differ on your apply.
FQDN=$(terraform output -raw service_fqdn) # db.svc.internal
DB=$(terraform output -raw data_private_ip) # e.g. 10.31.1.204Confirm the failure
nc -vz -w 5 "$FQDN" 5432
# Ncat: Version 7.93 ( https://nmap.org/ncat )
# Ncat: Could not resolve hostname "db.svc.internal": Name or service not known.
# QUITTING.Could not resolve hostname, immediately. No SYN was ever sent. Compare that against the timeout
you would get from a routing or NACL problem — this failure happens in the resolver library, before
the network is involved at all.
Prove the network is fine
This is the step that collapses most of the checklist.
nc -vz -w 5 "$DB" 5432
# Ncat: Connected to 10.31.1.204:5432.
# And confirm you are talking to the listener, not just completing a handshake
nc -w 3 "$DB" 5432
# lab-05-service-okPeering, both route tables, the security group, and the listener are all working. Whatever is wrong is confined to name resolution.
Ask the resolver directly
dig +noall +comments +answer "$FQDN"
# ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 24187
# ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1NXDOMAIN — the resolver is answering, and its answer is that this name does not exist. Note what
that rules out. A resolver that was unreachable would time out; a VPC with enableDnsSupport off
would fail differently. This is a healthy resolver reporting an authoritative negative.
Confirm which resolver answered, and that it is the VPC's own:
dig +short "$FQDN" @169.254.169.253
# (empty)
grep nameserver /etc/resolv.conf
# nameserver 10.30.0.210.30.0.2 is VPC base + 2, which is correct. The resolver is the right one. It simply has nothing
to say about this zone.
Ask the same question from the other side
Open a second session on the database host and run the identical query.
aws ssm start-session --target "$(terraform output -raw data_instance_id)"
dig +short db.svc.internal
# 10.31.1.204The same name, the same query, two different answers depending on which VPC you ask from. That is the finding, and it points at exactly one class of cause: something about resolution is scoped to the VPC rather than to the network.
Look at the zone's associations
aws route53 get-hosted-zone --id "$(terraform output -raw hosted_zone_id)" \
--query 'VPCs' --output table
# ----------------------------------------
# | GetHostedZone |
# +-------------+------------------------+
# | VPCId | vpc-0d4e… (data VPC) |
# | VPCRegion | us-east-1 |
# +-------------+------------------------+One VPC. And the reverse query, from the application VPC's point of view:
aws route53 list-hosted-zones-by-vpc \
--vpc-id "$(terraform output -raw app_vpc_id)" \
--vpc-region us-east-1 \
--query 'HostedZoneSummaries'
# []Empty. As far as Route 53 is concerned, the application VPC has no private zones at all.
This debrief is part of Labs Pro
The root-cause analysis, packet-flow walkthrough, and Terraform remediation diff for this lab are available to Labs Pro members. One payment of $49, no subscription, and it covers every Pro lab now and later.
The brief, the reproduction steps, and the Terraform stay free — you can still solve this one yourself.
Already bought it? Sign in and it unlocks.