13.4 Root Cause Analysis for Auto Scaling & Container Failures
Key Takeaways
- EC2 Auto Scaling launch failures are diagnosed via DescribeScalingActivities, typically stemming from service quotas, subnet IP exhaustion, invalid launch template configurations, or InsufficientInstanceCapacity.
- Amazon ECS task terminations distinguish between Linux OOM killer termination (Exit Code 137, where container memory exceeds hard memory limits) and application crashes (Exit Code 1, uncaught exceptions).
- The ECS Task Execution Role grants permissions to the ECS agent/Fargate infrastructure (pulling ECR images, writing CloudWatch logs, decrypting secrets), while the ECS Task Role grants permissions to the application code inside the container.
- Amazon EKS workload failures require differentiating CrashLoopBackOff (application startup crash), OOMKilled (cgroup memory limit exceeded), and VPC CNI secondary IP exhaustion (mitigated via prefix delegation).
- AWS Health events and CloudTrail Lake SQL queries correlate application service degradation with underlying AWS physical host retirements and mutating control-plane API calls.
Root Cause Analysis for EC2 Auto Scaling Launch Failures
When an Amazon EC2 Auto Scaling group (ASG) fails to launch replacement instances or scale out during high traffic, application availability quickly degrades. Rather than guessing, DevOps engineers must query the scaling activities via the AWS CLI or console:
aws autoscaling describe-scaling-activities \
--auto-scaling-group-name production-asg \
--max-items 5
Diagnostic Matrix for Auto Scaling Launch Failures
Error Message in DescribeScalingActivities | Underlying Root Cause | Architectural Resolution |
|---|---|---|
You have reached your quota for number of instances for this instance type | The AWS account has breached its regional EC2 On-Demand or Spot vCPU Service Quota for the target instance family. | Request a service quota increase via AWS Service Quotas console; configure ASG Mixed Instances Policy across multiple instance families. |
Cannot create instance because the subnet has no available IP addresses | Subnet CIDR IP exhaustion. All available private IPv4 addresses in the target VPC subnets are consumed by existing instances, ENIs, or ALBs. | Add secondary CIDR blocks to the VPC; expand subnets; attach additional subnets across alternative Availability Zones to the ASG. |
The AMI ID 'ami-012345678' does not exist or architecture mismatch | The AMI specified in the Launch Template has been deregistered, deleted, lacks cross-account sharing permissions, or architecture mismatch (x86_64 vs. ARM64 Graviton). | Update Launch Template with valid, accessible AMI ID; verify instance type CPU architecture matches the compiled AMI architecture. |
The security group 'sg-xyz' does not exist | The Security Group referenced in the Launch Template was deleted, or belongs to a different VPC than the ASG subnets. | Ensure Security Groups belong to the exact VPC associated with the ASG subnets; update Launch Template to latest revision. |
InsufficientInstanceCapacity: We currently do not have sufficient capacity in the Availability Zone you requested | AWS physical infrastructure in that specific AZ lacks available host capacity for the requested instance family and size. | Implement an Auto Scaling Mixed Instances Policy with multiple instance families (e.g., m5.large, m5a.large, c5.large); deploy across 3+ Availability Zones. |
Amazon ECS Task & Service Failure Modes
Amazon Elastic Container Service (ECS) manages container lifecycle on EC2 container instances and AWS Fargate. When an ECS task stops unexpectedly, ECS records a Stopped Reason and Container Exit Code.
Decoding Container Exit Codes
When a container marked essential: true exits, ECS immediately stops all other containers in the task:
- Exit Code 137 (
SIGKILL- Out-Of-Memory Killer):- Root Cause: The container's memory consumption exceeded its allocated limit (
memoryparameter in task definition), or the sum of container memory exceeded the task-level memory limit. The Linux kernel OOM killer sent aSIGKILL(128 + 9 = 137) to terminate the container. - Resolution: Increase the container
memorylimit or task-level memory allocation in the task definition. Alternatively, tune application memory management (e.g., JVM heap limits-Xmx).
- Root Cause: The container's memory consumption exceeded its allocated limit (
- Exit Code 1 (Application Runtime Error):
- Root Cause: The application process exited with a general error (e.g., unhandled exception, syntax error, missing mandatory environment variable, database connection failure on startup).
- Resolution: Query Amazon CloudWatch Logs for the container log stream to inspect
stdout/stderrstack traces.
- Exit Code 143 (
SIGTERM):- Root Cause: Graceful termination (128 + 15 = 143). ECS sent a
SIGTERMsignal during a service deployment, Auto Scaling scale-in event, or task retirement. If the container does not exit within thestopTimeout(default 30 seconds), ECS sendsSIGKILL(Exit Code 137).
- Root Cause: Graceful termination (128 + 15 = 143). ECS sent a
- Exit Code 125: Docker daemon error (e.g., invalid docker run command parameters).
- Exit Code 126: The specified container entrypoint or command cannot be invoked (e.g., file permissions error:
permission denied). - Exit Code 127: The specified command was not found in the container's
PATH.
CannotPullContainerError
If the task stops before the application starts with CannotPullContainerError:
- ECR Authentication: Verify the ECS Task Execution Role has permissions to call
ecr:GetAuthorizationToken,ecr:BatchCheckLayerAvailability, andecr:BatchGetImage. - Network Routing: For tasks running on Fargate or EC2 in private subnets, outbound traffic to ECR must be routed through a NAT Gateway or interface VPC Endpoints (
com.amazonaws.region.ecr.api,com.amazonaws.region.ecr.dkr, and an S3 Gateway Endpointcom.amazonaws.region.s3to download image layers stored in S3).
Architectural Distinction: Task Role vs. Task Execution Role
| Dimension | ECS Task Execution Role (executionRoleArn) | ECS Task Role (taskRoleArn) |
|---|---|---|
| Who Uses It? | The AWS ECS Container Agent and Fargate infrastructure plane | The Application Code running inside the container |
| Primary Purpose | Infrastructure provisioning and container startup | Application runtime business operations |
| Required Permissions | - Pulling images from private Amazon ECR<br/>- Writing logs to Amazon CloudWatch Logs (logs:CreateLogStream, logs:PutLogEvents)<br/>- Decrypting secrets from AWS Secrets Manager / Parameter Store | - Reading/writing to Amazon S3<br/>- Querying Amazon DynamoDB<br/>- Publishing messages to Amazon SQS / SNS<br/>- Invoking other AWS microservices |
| Trust Principal | ecs-tasks.amazonaws.com | ecs-tasks.amazonaws.com |
Amazon EKS Workload & Networking Failures
Amazon Elastic Kubernetes Service (EKS) introduces Kubernetes-native failure abstractions that DevOps engineers must diagnose using kubectl and AWS telemetry.
1. Pod Failure States & Root Causes
CrashLoopBackOff: The application container starts, fails, crashes, and is restarted repeatedly by the kubelet with exponential backoff. Diagnosis: Runkubectl logs <pod-name> --previousto inspect logs from the crashed container before the restart.OOMKilled: The container exceeded its Kubernetes resource limit (resources.limits.memory). Diagnosis: Runkubectl describe pod <pod-name>, which revealsLast State: Terminated, Reason: OOMKilled, Exit Code: 137.ImagePullBackOff/ErrImagePull: The kubelet cannot pull the specified container image due to an invalid image tag, missing image pull secret, or unauthorized private registry.Pending: The pod cannot be scheduled onto any worker node. Diagnosis: Checkkubectl describe podunderEvents: FailedScheduling. Causes include insufficient CPU/memory requests (Insufficient cpu,Insufficient memory), node taints without matching tolerations, or conflictingnodeSelector/nodeAffinityrules.
2. AWS VPC CNI Secondary IP Exhaustion
The AWS VPC Container Network Interface (CNI) plugin assigns native VPC private IP addresses directly to pods. Each EC2 worker node can only attach a fixed number of ENIs, and each ENI supports a limited number of secondary private IPv4 addresses based on the EC2 instance type.
- The Failure: Pods remain in
Pendingor fail withFailedCreatePodSandBox: failed to assign an IP address to container. - The Resolution: Prefix Delegation: Rather than allocating individual secondary IP addresses per ENI slot, enable Prefix Delegation on the AWS VPC CNI:
kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
Prefix delegation assigns a /28 IPv4 subnet prefix (16 IP addresses) to each ENI slot instead of a single IP, dramatically increasing pod density per worker node without exhausting ENI limits.
Investigating Infrastructure Root Cause with AWS Health & CloudTrail
When multiple unrelated applications simultaneously experience intermittent connectivity, high latency, or sudden instance termination, the root cause often resides in the underlying AWS infrastructure rather than application code.
Correlating Telemetry
- AWS Health API: Query
DescribeEventsandDescribeAffectedEntitiesto verify if AWS has flagged degraded underlying hardware or scheduled retirement:
aws health describe-affected-entities \
--filter "eventArns=['arn:aws:health:us-east-1::event/EC2/AWS_EC2_PERSISTENT_INSTANCE_RETIREMENT_SCHEDULED/...']"
- CloudTrail Lake Forensics: When suspicious configuration drift or accidental resource termination occurs, use CloudTrail Lake to query multi-account, multi-region API logs with SQL:
SELECT
eventTime,
eventName,
userIdentity.arn AS actor,
requestParameters
FROM
eds-secops-trail
WHERE
eventName IN ('TerminateInstances', 'DeleteSecurityGroup', 'UpdateSecurityGroupRuleDescriptionsIngress')
AND eventTime > '2026-09-11 14:00:00'
ORDER BY
eventTime DESC;
An Amazon ECS service running on AWS Fargate experiences sudden task failures during periods of peak transaction volume. The tasks terminate abruptly, and the ECS console reports the task stopped reason: 'Essential container in task exited'. Inspection of the stopped container details shows Exit Code 137. The application logs in CloudWatch Logs show normal log output up to the exact moment of termination, with no uncaught exceptions or error stack traces. What is the root cause of this failure and how should the DevOps engineer resolve it?
During a flash sale, an e-commerce website hosted on Amazon EC2 instances behind an Application Load Balancer experiences an unexpected traffic surge. The Auto Scaling group attempts to scale out, but no new EC2 instances are launched. The AWS CLI command describe-scaling-activities returns the error: 'Failed: We currently do not have sufficient capacity in the Availability Zone you requested'. What is the most effective architectural modification to ensure reliable scale-out capacity during high-demand events?
A DevOps team deploys microservices on an Amazon EKS cluster with managed node groups across two private subnets. As the number of microservices increases, newly scheduled pods remain in a 'Pending' state. Running 'kubectl describe pod' shows the event: 'FailedCreatePodSandBox: failed to assign an IP address to container'. An inspection of the VPC subnets confirms that the subnets still have over 1,000 available IPv4 addresses. However, the worker nodes are m5.large instances that have already reached their maximum Elastic Network Interface (ENI) allocation. How should the engineer resolve this pod scheduling issue without replacing the existing m5.large worker nodes with larger, more expensive instances?