Skip to content
ProfessionalProVPC LatticeNACL / Security Groups

Lab 27: The Lattice Target That Would Only Talk To The Client

An application whose security group admits HTTP from the client security group, which is how everything else in the VPC is wired and which works. Put a VPC Lattice service in front of it and the same client gets nothing, the target reports unhealthy, and the rule that was supposed to admit the client was never going to see the client.

Debugging time
~30 min
Reading time
10 min
Reported by
Platform Engineering
Tier
Professional
INC-1908SEV-3InvestigatingOpened 2026-10-02 15:30 UTC

New VPC Lattice service returns errors; target unhealthy; same client reaches the application directly

Reported by Platform Engineering

We are piloting VPC Lattice for service-to-service calls. First service: the inventory API, one EC2 target, HTTP listener on 80, the VPC associated with the service network. Auth type is NONE for the pilot so nothing about IAM should be in the way.

The client cannot get a response through the service DNS name. The target shows UNHEALTHY in the target group. But the application is fine: from the same client instance, curl straight at the application's private IP returns 200 immediately.

The application's security group allows port 80 from the client's security group. That rule is how every service in this VPC is secured and it has worked for two years. We have not changed it.

What you are working with

One VPC, one subnet, two instances, one VPC Lattice service.

Starting state — a client, an application, and a service in front of it
VPC lab 10.27.0.0/16 Attached: VPC Lattice service. AZ a contains lab 10.27.1.0/24, holding Client, App.VPC lab 10.27.0.0/16AZ alabpublic10.27.1.0/24Clientsg-clientApp10.27.1.50, sg-app: 80 from sg-clientVPC Lattice serviceservice network association

The direct path from client to application is a packet whose source carries the client's security group, and sg-app admits it. The path through the Lattice service leaves the VPC's addressing entirely: the client talks to a link-local address, and the application receives a connection from a VPC Lattice address. sg-app has no rule for that, and the health checks arrive the same way.

ResourceConfiguration
Clientt3.micro, sg-client, egress all
Appt3.micro, 10.27.1.50, Python HTTP server on :80
sg-app inboundTCP 80 from sg-client, nothing else
Service networkauth_type = NONE, VPC associated, no association security groups
Serviceauth_type = NONE, HTTP listener on 80 → target group
Target groupINSTANCE, HTTP:80, health check GET / expecting 200
  1. EC2

    Client

    curl http://<service dns>/

  2. RTB

    DNS

    service name resolves to a link-local address

  3. VPCE

    VPC Lattice

    terminates the client connection, opens one to the target

  4. FILTER

    sg-app

    inbound: TCP 80 from sg-client

    Dropped — The connection to the target comes from a VPC Lattice address, not from an interface in sg-client. The only inbound rule names sg-client. Nothing matches, and the security group denies by default. Health checks take the same path and meet the same rule.

  5. DEST

    App

    never reached

The client is not the thing connecting to the application. VPC Lattice is. A rule that admits the client admits nothing on this path.

Scope and constraints

  • In scope: why a security group rule that works for direct traffic admits nothing through VPC Lattice, and what the source of Lattice traffic is.
  • Out of scope: auth policies (auth is NONE throughout), the service network association's own security groups, the listener, the target group, DNS. All correct.
  • The reporter is right that the application works directly and right that the rule has not changed. Both are evidence.
  • The fix is one inbound rule, and it is one that AWS's own documentation says is the only kind that can work here.

Deploy the broken state

cd lab-27-lattice-target-security-group
terraform init
terraform apply

About five minutes. The service, the target group attachment and the two associations each take a minute or two to become active. Wait for the target group to finish its initial health checks before reproducing:

aws vpc-lattice list-targets \
  --target-group-identifier "$(terraform output -raw target_group_id)" \
  --query 'items[].[id,status,reasonCode]' --output text
# i-0a1b…	UNHEALTHY	HealthCheckFailed

UNHEALTHY is the broken state. If it still says INITIAL, wait a minute.