floci-io/floci · error · AwsException
StackSetNotEmptyException
StackSetNotEmptyException
Error message
StackSet is not empty. Delete all stack instances first.
What it means
StackSetNotEmptyException (HTTP 409) from deleteStackSet when the StackSet still has stack instances. Floci enforces AWS's ordering: every (account, region) instance must be deleted (or retained) via DeleteStackInstances before the StackSet itself can be removed.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/cloudformation/StackSetService.java:137
if (description != null) {
ss.setDescription(description);
}
stackSets.put(name, ss);
// Re-apply the updated definition to every existing instance, refreshing each record.
List<StackInstance> deployed = new ArrayList<>();
for (StackInstance inst : listStackInstances(name, null, null)) {
StackInstance updated = deployInstance(ss, inst.getAccount(), inst.getRegion(), UPDATE_CHANGE_SET, "UPDATE");
instances.put(instanceKey(name, updated.getAccount(), updated.getRegion()), updated);
deployed.add(updated);
}
return recordOperation(name, "UPDATE", deriveOperationStatus(deployed));
}
public void deleteStackSet(String name) {
getStackSetOrThrow(name);
if (!listStackInstances(name, null, null).isEmpty()) {
throw new AwsException("StackSetNotEmptyException",
"StackSet is not empty. Delete all stack instances first.", 409);
}
stackSets.delete(name);
LOG.infov("Deleted StackSet: {0}", name);
}
// ── Instances ──────────────────────────────────────────────────────────────
public StackSetOperation createStackInstances(String name, List<String> accounts, List<String> regions) {
StackSet ss = getStackSetOrThrow(name);
if (accounts == null || accounts.isEmpty() || regions == null || regions.isEmpty()) {
throw new AwsException("ValidationError",
"Accounts and Regions must each contain at least one value", 400);
}
List<StackInstance> deployed = new ArrayList<>();
for (String account : accounts) {
for (String region : regions) {
StackInstance inst = deployInstance(ss, account, region, INSTANCE_CHANGE_SET, "CREATE");View on GitHub (pinned to 62ff490619)
Solutions
- List remaining instances: aws ... cloudformation list-stack-instances --stack-set-name <name>.
- Delete all instances: aws ... cloudformation delete-stack-instances --stack-set-name <name> --accounts <a> --regions <r> --no-retain-stacks (repeat for every account/region pair).
- Then call DeleteStackSet.
- Use --retain-stacks instead of --no-retain-stacks only if you intentionally want the underlying stacks left in place.
Example fix
# before aws ... cloudformation delete-stack-set --stack-set-name shared # after aws ... cloudformation delete-stack-instances --stack-set-name shared \ --accounts 111122223333 --regions us-east-1 --no-retain-stacks aws ... cloudformation delete-stack-set --stack-set-name shared
Defensive patterns
Strategy: validation
Validate before calling
var remaining = cfn.listStackInstances(req -> req.stackSetName(name)).summaries();
if (!remaining.isEmpty()) {
// delete every (account, region) pair first
remaining.forEach(i -> cfn.deleteStackInstances(req -> req
.stackSetName(name).accounts(i.account()).regions(i.region()).retainStacks(false)));
}
cfn.deleteStackSet(req -> req.stackSetName(name)); Try / catch
catch StackSetNotEmptyException (409): call ListStackInstances, issue DeleteStackInstances for every account/region pair with --no-retain-stacks, wait for the operation to finish, then retry DeleteStackSet once.
Prevention
- Teardown order: instances before stack set, always
- Pass --no-retain-stacks unless the underlying stacks must survive
- Drive deletion from ListStackInstances output so no pair is missed
When it happens
Trigger: DeleteStackSet called while instances exist — i.e., CreateStackInstances ran earlier and DeleteStackInstances was never called, or was called with a subset of accounts/regions.
Common situations: Cleanup scripts that delete only the StackSet, forgetting the instance layer; DeleteStackInstances invoked with fewer accounts/regions than were created; asynchronous instance deletion not yet finished when DeleteStackSet is issued.
Related errors
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/19e10c21f793b3ed.
Report an issue: GitHub.