<@ULVA73B9P> I have an ecs push workpool in prefec...
# ask-marvin
l
@Marvin I have an ecs push workpool in prefect cloud. the ecs cluster is backed by an autoscaling group with managed scaling. it scales between 0 and 6 m5a.xlarge instances. when the cluster has scaled to 0 jobs submitted to prefect fail with the message
does not appear to have any container instances associated with it. Confirm that you have EC2 container instances available
but if i submit a task directly in AWS it correctly places the task in the
provisioning
state while the ASG spins up EC2 instances to run the task.
m
thought for 219.7 seconds
Thanks for the clear description — I’ve seen this exact behavior with ECS + EC2 when the cluster is scaled to zero. What’s happening - When your Prefect ECS pool submits a task with launchType=EC2, the ECS RunTask API fails immediately if there are no registered container instances in the cluster. That’s the error you see: “does not appear to have any container instances…”. - When you “Run task” directly in the AWS console, it likely uses the cluster’s capacity provider strategy. With an EC2 capacity provider that has managed scaling, ECS will place the task into PROVISIONING and the ASG spins up instances. How to fix it in Prefect (Prefect 3.x) Configure your ECS work pool to use a capacity provider strategy instead of a launch type. That allows ECS to queue/provision capacity the same way the console does. Steps (Cloud UI) 1) Go to Work Pools > your ECS pool > Edit. 2) In Variables: - Remove/clear any
launch_type
setting (you cannot set both). - Add a capacity provider strategy that points at your EC2 capacity provider (the one attached to your ASG with managed scaling). 3) Save. If you prefer editing as JSON, it’ll look roughly like this (adjust keys/values to match your setup and the UI form; do not include both launch_type and capacity providers):
Copy code
{
  "cluster": "my-ecs-cluster",
  "task_definition_arn": "arn:aws:ecs:region:acct:task-definition/my-task:1",
  "capacity_provider_strategy": [
    {
      "capacity_provider": "my-ec2-capacity-provider",
      "weight": 1,
      "base": 0
    }
  ],
  "subnets": [
    "subnet-abc",
    "subnet-def"
  ],
  "security_groups": [
    "sg-123"
  ]
}
Notes: - Use the exact capacity provider name shown in ECS (the one linked to your ASG with managed scaling). - Do not set
launch_type
when using a capacity provider strategy — ECS will reject it, and Prefect will fall back to a launch type if it’s present. - If your cluster has a default capacity provider strategy and you want to use that, remove
launch_type
and leave the capacity provider strategy empty; Prefect should not override it. However, explicitly setting the strategy in the pool variables is the most reliable. Alternatives/workarounds - Switch to Fargate (set
launch_type: "FARGATE"
), which doesn’t rely on EC2 instances. - Keep min capacity at 1 in the ASG so there’s always a registered instance. - If spin-up sometimes takes longer than Prefect’s retry window, we can look at logs and timing; the ECS worker will retry task creation a few times, but very long scale-up times can still cause failures. If you share your current ECS work pool variables (redact any secrets), I can spot-check the exact field names and suggest the minimal change. Also, here’s the ECS guide for reference: Prefect ECS guide.
l
@Marvin i removed the launch type from my template completely and configured the capacity provider strategy. Now I get this error:
Copy code
Flow run could not be submitted to infrastructure: Task definition does not have 'FARGATE' in 'requiresCompatibilities' and cannot be used with launch type 'FARGATE'
Is prefect defaulting to
FARGATE
?
m
thought for 224.2 seconds
Short answer: yes — by default the ECS worker uses a FARGATE launch type if you don’t explicitly unset it. That’s why AWS is complaining that your task definition doesn’t support FARGATE. What to do You need to ensure the worker submits with a capacity provider strategy and no launchType at all. Two reliable ways to do that: - Set launch_type to null in your pool variables - In your ECS work pool’s Variables JSON, explicitly set:
Copy code
{
  "launch_type": null,
  "capacity_provider_strategy": [
    {
      "capacity_provider": "my-ec2-capacity-provider",
      "weight": 1,
      "base": 0
    }
  ],
  "cluster": "my-ecs-cluster",
  "task_definition_arn": "arn:aws:ecs:region:acct:task-definition/my-task:1",
  "subnets": [
    "subnet-..."
  ],
  "security_groups": [
    "sg-..."
  ]
}
- Prefect will ignore launchType when it’s null and use your capacity provider strategy, allowing ECS managed scaling to place the task in PROVISIONING when there are 0 instances. - Or remove the launchType field from your base job template - Edit the ECS pool’s base job template and remove the line:
Copy code
"launchType": "{{ launch_type }}"
- Keep:
Copy code
"capacityProviderStrategy": "{{ capacity_provider_strategy }}"
- Then make sure your pool variables include the strategy array shown above. Important notes - Don’t set both
launch_type
and
capacity_provider_strategy
. If
launch_type
is set (and it defaults to FARGATE), AWS treats it as FARGATE even if you provided a strategy. - Use an EC2-compatible task definition when using an EC2 capacity provider. It does not need FARGATE in `requiresCompatibilities`; it can be EC2 or empty (but must match your networking mode and other settings). - If you created the task definition for Fargate originally, it likely won’t run under EC2; point Prefect at an EC2-compatible task def (or let the worker register one that is). If you paste your current ECS work pool variables (redact secrets), I can spot-check exactly what to tweak. Also, here’s the ECS guide for reference: Prefect ECS guide.
l
m
thought for 30.3 seconds
You’re exactly right — the worker code defaults to FARGATE unless
launch_type == "EC2"
. With only a capacity provider strategy set in variables, the worker still rendered a
launchType
of FARGATE, hence the error. To use EC2 capacity providers (and allow PROVISIONING while the ASG spins up), you need the RunTask request to have no
launchType
at all. The most reliable fix is to remove
launchType
from your pool’s base job template. Do this: 1) Edit your ECS work pool’s Base job template. 2) In
job_configuration.task_run_request
, delete the line:
Copy code
"launchType": "{{ launch_type }}",
3) Keep the capacity provider strategy:
Copy code
"capacityProviderStrategy": "{{ capacity_provider_strategy }}"
4) In your pool Variables, supply your capacity provider strategy and do not set `launch_type`:
Copy code
{
  "capacity_provider_strategy": [
    {
      "capacity_provider": "my-ec2-capacity-provider",
      "weight": 1,
      "base": 0
    }
  ],
  "cluster": "my-ecs-cluster",
  "task_definition_arn": "arn:aws:ecs:region:acct:task-definition/my-ec2-task:1",
  "subnets": [
    "subnet-..."
  ],
  "security_groups": [
    "sg-..."
  ]
}
Notes: - Do not include both
capacityProviderStrategy
and
launchType
— AWS will either reject it, or (as you saw) the worker default will force FARGATE. - Make sure your task definition is EC2-compatible (not FARGATE-only). - If you prefer CLI, you can update the base job template file and then run:
Copy code
prefect work-pool update "<your-ecs-pool>" --base-job-template ./ecs-template.json
Reference: ECS guide Prefect ECS guide If you want, paste your current base job template and variables (redact secrets) and I’ll mark exactly what to remove/change. If you’d like, I can also open an issue to propose that when
capacity_provider_strategy
is set, the worker should omit
launchType
instead of defaulting to FARGATE.
l
@Marvin I do not have a launchType in my job template.
Copy code
"task_run_request": {
      "tags": "{{ labels }}",
      "cluster": "{{ cluster }}",
      "overrides": {
        "cpu": "{{ cpu }}",
        "memory": "{{ memory }}",
        "taskRoleArn": "{{ task_role_arn }}",
        "containerOverrides": [
          {
            "cpu": "{{ cpu }}",
            "name": "{{ container_name }}",
            "memory": "{{ memory }}",
            "command": "{{ command }}",
            "environment": "{{ env }}"
          }
        ]
      },
      "taskDefinition": "{{ task_definition_arn }}",
      "capacityProviderStrategy": "{{ capacity_provider_strategy }}"
    },
m
thought for 52.6 seconds
You’re right, and thanks for the precise code reference — the worker currently does this: - If
launch_type == "EC2"
, use EC2 - Otherwise, assume FARGATE So even if your base job template omits
launchType
, the worker still ends up supplying
launchType="FARGATE"
when constructing the RunTask call. That’s why you’re seeing:
Copy code
Task definition does not have 'FARGATE' in 'requiresCompatibilities' and cannot be used with launch type 'FARGATE'
This means the current ECS push worker does not honor a “capacity provider strategy only” configuration; it still forces a launch type. Your link pinpoints the logic: code reference. Best available workarounds right now - If you can use Fargate: update your task definition to include Fargate compatibilities and Fargate networking; then keep using the push pool. - If you must use EC2 capacity providers with scale-from-zero: - Set ASG min capacity > 0 so EC2 instances are always registered (not ideal, but avoids the immediate launchType issue), or - Switch from a push pool to a pull worker that you run yourself, and pin/patch a worker that omits
launchType
when
capacity_provider_strategy
is set. That way ECS will place tasks in PROVISIONING and trigger managed scaling. (With a push pool, the code path runs in Prefect Cloud and can’t be patched by you.) Next steps - If you’d like, I can open a GitHub issue on your behalf describing this behavior (when
capacity_provider_strategy
is provided, the worker should omit
launchType
instead of defaulting to FARGATE). Your code link is perfect supporting evidence. - If you share your ECS work pool variables (redact secrets), I’ll sanity-check that the capacity provider names/strategy look good for when this is fixed. References - Prefect ECS guide: Prefect ECS guide - AWS RunTask docs (capacity providers vs launch type): AWS RunTask
l
@Marvin open a github issue
m
thought for 40.2 seconds
I can’t directly open a GitHub issue from here, but the exact problem you’re hitting is already tracked and discussed: - Setting capacityProviderStrategy not working in Push Work Pool: #13030 - Related docs gap: #13969 Given #13030 matches your case, I recommend adding your details there (upvote + comment). Here’s a ready-to-post comment you can paste into that issue:
Copy code
We’re seeing the same behavior with ECS push work pools and EC2 capacity providers (cluster autoscaling to 0).

Setup:
- ECS cluster with an EC2 capacity provider (ASG with managed scaling, min=0)
- Prefect Cloud ECS push work pool
- Base job template does NOT include "launchType"
- Pool variables set "capacity_provider_strategy" to our EC2 capacity provider
- Task definition is EC2-compatible (no Fargate requiresCompatibilities)

Observed:
- Flow run submission fails with:
  "Task definition does not have 'FARGATE' in 'requiresCompatibilities' and cannot be used with launch type 'FARGATE'"

Expected:
- When a capacityProviderStrategy is supplied, the ECS RunTask request should omit "launchType" so ECS can place the task into PROVISIONING and trigger ASG scale-up.

Code reference:
- Worker defaults to FARGATE unless launch_type == "EC2":
  <https://github.com/PrefectHQ/prefect/blob/28d8999852ced8f119016467505890d10f42602c/src/integrations/prefect-aws/prefect_aws/workers/ecs_worker.py#L1051-L1054>

Environment:
- Prefect: <your version>
- prefect-aws: <your version>
- Prefect Cloud
- Region: <your region>

Workarounds we considered:
- Use Fargate (not applicable for EC2-only or GPU workloads)
- Keep ASG min > 0 (avoids failure but removes scale-to-zero)
- Run a pull worker and patch logic to omit launchType when capacityProviderStrategy is provided

Request:
- When capacity_provider_strategy is set, have the ECS worker omit launchType instead of defaulting to FARGATE.
If you still prefer a brand new issue rather than commenting on #13030, say the word and I’ll draft a full issue body you can file.