Introduction
ECS services manage long-running tasks. When a service can't schedule tasks, the desired count is not met, and applications are unavailable or underscaled. Tasks may be stuck in PENDING, failing to start, or not being placed at all.
Symptoms
Service events show placement failures:
```bash $ aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].events[:5]'
"service my-service was unable to place a task because the container instances did not have enough available resources" ```
Running count less than desired:
```bash $ aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].[desiredCount,runningCount,pendingCount]'
[5, 2, 0] # Desired 5, only 2 running ```
Task placement failure:
```bash $ aws ecs describe-tasks --cluster my-cluster --tasks TASK_ID \ --query 'tasks[*].[lastStatus,stoppedReason]'
["STOPPED", "Task failed to start"] ```
Common Causes
- 1.Insufficient cluster resources - Not enough CPU/memory on instances
- 2.Task definition invalid - Container configuration errors
- 3.IAM role missing - Execution or task role issues
- 4.Capacity provider issues - Fargate or EC2 capacity unavailable
- 5.Network configuration errors - Wrong subnets or security groups
- 6.Placement constraints - Task can't be placed due to constraints
- 7.Service quota limits - Account limits reached
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Check Service and Task Status
```bash # Get service details aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].[desiredCount,runningCount,pendingCount,status]'
# Get recent service events aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].events[:5].[createdAt,message]'
# Check task status aws ecs list-tasks --cluster my-cluster --service-name my-service \ --query 'taskArns'
# Describe failed tasks aws ecs describe-tasks --cluster my-cluster --tasks TASK_ARN \ --query 'tasks[*].[lastStatus,stoppedReason,containers[*].reason]' ```
Step 2: Check Task Definition
```bash # Get current task definition aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].taskDefinition'
# Describe task definition aws ecs describe-task-definition --task-definition TASK_DEF_NAME \ --query 'taskDefinition.{Family:family,Memory:memory,CPU:cpu,Containers:containerDefinitions[*].[name,memory,memoryReservation,cpu]}'
# Verify: # - CPU and memory are within limits # - Container ports are valid # - Image exists and is accessible ```
Step 3: Check Container Instance Resources (EC2)
```bash # List container instances aws ecs list-container-instances --cluster my-cluster
# Check instance resources aws ecs describe-container-instances \ --cluster my-cluster \ --container-instances INSTANCE_ARN \ --query 'containerInstances[*].[registeredResources,remainingResources]'
# Look at: # - remainingResources for CPU, MEMORY, PORTS # - If low, need more instances or larger instance types
# Check instance count aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].[launchType,platformVersion]' ```
Step 4: Check Capacity Provider (Fargate)
```bash # For Fargate, check capacity provider aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].capacityProviderStrategy'
# Fargate requires: # - Correct CPU/memory combination (see Fargate limits) # - Network configuration (awsvpc mode) # - Task has execution role
# Fargate CPU/Memory combinations: # 256 (.25 vCPU): 512MB-2GB # 512 (.5 vCPU): 1GB-4GB # 1024 (1 vCPU): 2GB-8GB # 2048 (2 vCPU): 4GB-16GB # 4096 (4 vCPU): 8GB-30GB ```
Step 5: Verify IAM Roles
```bash # Check task execution role aws ecs describe-task-definition --task-definition my-task \ --query 'taskDefinition.executionRoleArn'
# Execution role needs: # - ecr:GetAuthorizationToken # - ecr:BatchCheckLayerAvailability # - ecr:GetDownloadUrlForLayer # - ecr:BatchGetImage # - logs:CreateLogStream # - logs:PutLogEvents
# Check task role aws ecs describe-task-definition --task-definition my-task \ --query 'taskDefinition.taskRoleArn'
# Verify role exists aws iam get-role --role-name ecsTaskExecutionRole ```
Step 6: Check Network Configuration
```bash # For awsvpc network mode (Fargate and some EC2) aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].networkConfiguration'
# Verify: # - Subnets exist and are in correct VPC # - Security groups allow required traffic # - For Fargate with public IP, assignPublicIp is ENABLED
# Check subnet exists aws ec2 describe-subnets --subnet-ids subnet-12345
# Check security group aws ec2 describe-security-groups --group-ids sg-12345 ```
Step 7: Check Placement Constraints
```bash # Get service placement constraints aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].placementConstraints'
# Common constraints: # - distinctInstance: Only one task per instance # - memberOf: Expression matching instance attributes
# If constraints too restrictive, tasks can't be placed # Update service to remove or relax constraints aws ecs update-service \ --cluster my-cluster \ --service my-service \ --placement-constraints '[]' ```
Step 8: Check Service Quotas
```bash # Check Fargate quotas aws service-quotas get-service-quota \ --service-code fargate \ --quota-code L-3032A538
# Check EC2 quotas aws service-quotas get-service-quota \ --service-code ec2 \ --quota-code L-12345
# If hitting limits, request increase aws service-quotas request-service-quota-increase \ --service-code fargate \ --quota-code L-3032A538 \ --desired-value 100 ```
Step 9: Run Test Task
```bash # Run task manually to debug aws ecs run-task \ --cluster my-cluster \ --task-definition my-task \ --launch-type FARGATE \ --network-configuration 'awsvpcConfiguration={subnets=[subnet-12345],securityGroups=[sg-12345],assignPublicIp=ENABLED}'
# Check task details aws ecs describe-tasks --cluster my-cluster --tasks TASK_ARN \ --query 'tasks[*].[lastStatus,containers[*].lastStatus,containers[*].reason]' ```
Step 10: Check Container Image Access
```bash # For ECR images aws ecr describe-repositories --repository-names my-repo
# Test image pull docker pull account.dkr.ecr.region.amazonaws.com/my-repo:latest
# Verify ECR permissions allow task execution role aws ecr get-repository-policy --repository-name my-repo
# If private registry, check registry credentials aws secretsmanager get-secret-value --secret-id my-registry-creds ```
Common Scheduling Errors
| Error | Cause | Fix |
|---|---|---|
| "insufficient resources" | Not enough CPU/memory | Add instances or reduce task size |
| "cannot pull container" | Image access denied | Check ECR permissions |
| "network configuration invalid" | Wrong subnets/SG | Fix network config |
| "task definition inactive" | Deregistered task def | Use active version |
| "service quota exceeded" | Account limits | Request increase |
Verification
```bash # Update service if needed aws ecs update-service \ --cluster my-cluster \ --service my-service \ --task-definition my-task:NEW_VERSION \ --force-new-deployment
# Wait for service to stabilize aws ecs wait services-stable --cluster my-cluster --services my-service
# Check running count matches desired aws ecs describe-services --cluster my-cluster --services my-service \ --query 'services[*].[desiredCount,runningCount]'
# Should show matching counts ```
Related Issues
- [Fix AWS ECS Task Stuck in Pending](/articles/fix-aws-ecs-task-pending)
- [Fix AWS ECS Service Unstable](/articles/fix-aws-ecs-service-unstable)
- [Fix AWS ECS Fargate CPU Memory Wrong](/articles/fix-aws-ecs-fargate-cpu-memory-wrong)
Related Articles
- [AWS troubleshooting: Fix IAM Permission Denied - Complete Tro](fix-iam-permission-denied)
- [AWS cloud troubleshooting: AWS ACM Certificate Pending Validation Because the](aws-acm-certificate-pending-validation-wrong-route53-zone)
- [AWS cloud troubleshooting: AWS ALB Returns 502 Because the Target Closed the ](aws-alb-502-target-closed-connection-keepalive-timeout-mismatch)
- [AWS cloud troubleshooting: Fix AWS ALB CreateListener TargetGroupNotFound Err](aws-alb-createlistener-targetgroupnotfound)
- [AWS cloud troubleshooting: Fix Aws Alb Lambda 502 Bad Gateway Issue in AWS](aws-alb-lambda-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix AWS ECS Service Not Scheduling Tasks", "description": "Troubleshoot ECS service scheduling failures. Fix task definitions, capacity providers, and resource constraints.", "url": "https://www.fixwikihub.com/fix-aws-ecs-service-not-scheduling", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-01T20:27:26.986Z", "dateModified": "2026-04-01T20:27:26.986Z" } </script>