Skip to content

[Bug]: AWS cluster fleets fail with NO_OFFERS when using a Capacity Block reservation #4344

Closed

Description

@r4victor

Steps to reproduce

  1. Purchase an AWS Capacity Block (e.g. p5.48xlarge) with enough available instances for the fleet.
  2. Apply a fleet that targets it with cluster placement:
type: fleet
name: cb-cluster
backends: [aws]
instance_types: [p5.48xlarge]
nodes: 2
placement: cluster
resources:
  gpu: 8
spot_policy: on-demand
reservation: cr-<capacity-block-id>

Actual behaviour

dstack apply shows a valid offer in the plan, but the master instance is terminated with NO_OFFERS ("All offers failed"), and so is the fleet. The same fleet without placement: cluster provisions successfully, but it can't run multi-node tasks, because those require a cluster fleet.

The master instance's launch request includes the fleet's cluster placement group, which AWS rejects for Capacity Blocks: "Capacity Blocks do not support placement groups. You can't specify a placement group when you launch instances into a Capacity Block" (docs). dstack only skips placement groups for reservations when are_placement_groups_compatible_with_reservations() returns False:

cluster_context is not None
and cluster_context.is_current_instance_master
and instance_offer.backend in BACKENDS_WITH_PLACEMENT_GROUPS_SUPPORT
and isinstance(compute, ComputeWithPlacementGroupSupport)
and (
compute.are_placement_groups_compatible_with_reservations(instance_offer.backend)
or instance_configuration.reservation is None
)
):

GCP overrides it, but AWS inherits the default True:

def are_placement_groups_compatible_with_reservations(self, backend_type: BackendType) -> bool:
"""
Whether placement groups can be used for instances provisioned in reservations.
Arguments:
backend_type: matches the backend type of this compute, unless this compute is a proxy
for other backends (dstack Sky)
"""
return True

So the AWS backend sends Placement.GroupName together with MarketType: capacity-block. The ClientError is only logged, and every offer ends up counted as failed:

placement_group_name=placement_group.name if placement_group else None,
enable_efa=enable_efa,
max_efa_interfaces=max_efa_interfaces,
reservation_id=instance_config.reservation,
is_capacity_block=is_capacity_block,
tenancy=reservation_tenancy,
)
)
except botocore.exceptions.ClientError as e:
logger.warning("Got botocore.exceptions.ClientError: %s", e)
if e.response["Error"]["Code"] == "InvalidParameterValue":
msg = e.response["Error"].get("Message", "")
raise ComputeError(f"Invalid AWS request: {msg}")
continue

The fleet plan doesn't catch this because planning never creates a placement group or launches an instance. The same check also gates placement groups in jobs_submitted.py, so run-triggered provisioning into a cluster fleet is affected too.

Expected behaviour

A cluster fleet in an AWS Capacity Block provisions all nodes without a placement group. AWS already co-locates Capacity Block instances in an EC2 UltraCluster, and EFA is still enabled. Placement groups should still be used with regular on-demand capacity reservations.

dstack version

master (90887d0)

Additional information

A possible fix is to make are_placement_groups_compatible_with_reservations() reservation-aware (e.g. pass the reservation) and have AWS return False when ReservationType == "capacity-block".

The docs for placement: cluster also don't say what it maps to on each backend (on AWS, an EC2 cluster placement group).

Activity

  1. self-assigned this
    on Oct 7, 2026
  2. added a commit that references this issue on Oct 7, 2026
    07174d9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions