TroubleshootingAWS deployments

Like the GCP page, everything here comes from real campaign deployments with published, root-caused failures (reliability ledger). Patterns are listed roughly in order of how often we see them.

ALB returns 502 / 503 / 504 while the app boots

Symptom: the load balancer URL serves errors for the first minutes after apply.

Cause: those pages are generated by the ALB itself (check the Server: awselb response header) while no healthy target is registered yet. A JVM app behind a fresh target group commonly takes 1–3 minutes to pass its first health checks.

Platform handling: automatic. The health model explicitly does not count LB-generated 502/503/504 as “up” — verification waits for real application responses. We closed a failure class in our own campaigns where a lucky LB page could look like a healthy app; it can’t anymore.

Your action: patience during boot. If it’s still LB-erroring after ~5 minutes, check the target group’s health-check path matches a route your app actually serves.

”InsufficientInstanceCapacity” in an availability zone

Symptom: EC2/ASG creation fails because the chosen AZ has no capacity for the instance type right now.

Platform handling: automatic — a deterministic fixer rotates the deployment to a sibling AZ and retries. You’ll see the rotation in the run log.

Java apps OOM-killed on t-family micro/small instances

Symptom: app boots, dies silently, container restarts — often in a loop; sometimes the instance becomes unreachable.

Cause: default JVM heap behavior on 1GB-and-under instances.

Platform handling: automatic. Undersized instance types are bumped (architecture-preserving, e.g. t3.micro → t3.medium), the container gets a restart policy, and JAVA_TOOL_OPTIONS bounds the heap. If you pinned an instance type yourself and it’s too small, the agent will tell you rather than deploy a crash-loop.

Quota exhaustion: VPCs, Elastic IPs, vCPUs

Symptom: Terraform fails with VpcLimitExceeded, AddressLimitExceeded, or an On-Demand vCPU limit error.

New AWS accounts commonly start with 5 VPCs and 5 Elastic IPs per region and low On-Demand/Fargate vCPU quotas — numbers a handful of isolated environments will hit.

Platform handling: partial. Preflight checks headroom before applying, and teardown sweeps release addresses and delete deployment VPCs (including the NAT gateway → EIP chain that most often leaks). Raising limits is account-owner territory:

# Check where you stand
aws service-quotas get-service-quota \
  --service-code vpc --quota-code L-F678F1CE   # VPCs per region
aws service-quotas get-service-quota \
  --service-code ec2 --quota-code L-0263D0A3   # EC2-VPC Elastic IPs
 
# Request an increase
aws service-quotas request-service-quota-increase \
  --service-code vpc --quota-code L-F678F1CE --desired-value 15
If you’re cleaning leaked resources by hand, order matters: NAT gateway → (wait for delete) → release EIP → detach+delete internet gateway → subnets → security groups → VPC. Deleting the VPC first fails while dependencies exist.

ECR repository name collision

Symptom: image push fails with “repository already exists” after a previous failed run.

Platform handling: automatic — a fixer renames the deployment’s repo on collision. Stale repos from failed runs are removed by teardown; if one lingers: aws ecr delete-repository --repository-name <name> --force.

EKS: metrics panel empty on a healthy cluster

Symptom: logs are flowing but the Metrics panel shows nothing for an EKS deployment.

Cause: pod-level EKS metrics require the CloudWatch Container Insights add-on, which isn’t installed by default.

Platform handling: automatic fallback — when Container Insights is absent, the platform resolves the cluster’s node instances and shows node-level EC2 metrics instead, so the panel is never structurally blank.

Your action (optional): install Container Insights for pod-level granularity; the platform uses it automatically once present.

Zip-source deploys: the CodeBuild step

Deployments from an uploaded source archive build the container image in AWS CodeBuild inside your account before rollout. Two things follow:

  • The IAM role you connected needs CodeBuild + ECR permissions (see Connect AWS — the app-deployment permission set).
  • Build failures surface in the run log with the CodeBuild log link — a compile error in your app shows up here, not as an infra error.

Fargate tasks can’t reach external databases

Symptom: service healthy, but connections to an external Redis / MongoDB / Postgres time out.

Cause: tasks in private subnets have no internet path unless the topology includes a NAT gateway (or your stores are reachable via VPC peering/endpoints).

Platform handling: generated topologies include the egress path their declared dependencies need. If you trimmed the topology by hand or your store’s firewall allowlists IPs, allow the NAT gateway’s EIP — that’s the address your tasks egress from.

Region and service opt-ins

Some services and newer regions require explicit opt-in (Console → Account settings → Regions). Symptoms are auth-shaped errors in a region you never enabled. Enable the region or deploy to an enabled one.

When self-healing gives up

Same contract as GCP: the ladder is bounded, every attempt is in the run log, and the final finding names the blocker. Quota and app-contract classes are yours; anything else, send us the deployment ID. See How self-healing works.

See also

Was this page helpful?