floci-io/floci · error · AwsException
KeyGroupAlreadyExists
KeyGroupAlreadyExists
Error message
A key group with this name already exists.
What it means
CloudFrontService.validateUniqueKeyGroupName throws KeyGroupAlreadyExists (HTTP 409) when another stored key group (excluding the current id during updates) already uses the same Name. CloudFront key group names are globally unique per account, and the emulator scans the key group store on CreateKeyGroup and UpdateKeyGroup to enforce it.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/cloudfront/CloudFrontService.java:1096
"PreconditionFailed",
"The precondition in one or more request-header fields evaluated to false.",
412);
}
if (keyGroupInUse(id)) {
throw new AwsException(
"ResourceInUse",
"Cannot delete this resource because it is in use.",
409);
}
keyGroupStore.delete(id);
}
private void validateUniqueKeyGroupName(String name, String excludedId) {
boolean duplicate = keyGroupStore.scan(group -> true).stream()
.anyMatch(group -> !Objects.equals(excludedId, group.getId())
&& Objects.equals(name, group.getName()));
if (duplicate) {
throw new AwsException(
"KeyGroupAlreadyExists",
"A key group with this name already exists.",
409);
}
}
public List<KeyGroup> listKeyGroups(String marker, int maxItems) {
List<KeyGroup> all = new ArrayList<>(keyGroupStore.scan(k -> true));
all.sort((a, b) -> a.getId().compareTo(b.getId()));
return paginate(all, marker, maxItems, KeyGroup::getId);
}
private static void validatePublicKey(PublicKey key) {
if (key == null
|| key.getCallerReference() == null
|| key.getCallerReference().isBlank()
|| key.getName() == null
|| key.getName().isBlank()View on GitHub (pinned to 62ff490619)
Solutions
- Use a unique Name per create (suffix with UUID or run id) or delete the existing group first.
- On update, either keep the current Name or verify the target name is unused via ListKeyGroups.
- Add teardown or unique naming to fixtures so reruns cannot collide.
Example fix
// before
createKeyGroup("kg", keys); // ok
createKeyGroup("kg", otherKeys); // 409
// after
createKeyGroup("kg-" + UUID.randomUUID(), keys); Defensive patterns
Strategy: validation
Validate before calling
boolean keyGroupNameTaken(CloudFrontClient client, String name, String excludeId) {
return client.listKeyGroups(r -> r.build()).keyGroupList().items().stream()
.anyMatch(g -> name.equals(g.keyGroup().name()) && !g.id().equals(excludeId));
} Try / catch
try {
return client.createKeyGroup(r -> r.keyGroupConfig(cfg));
} catch (KeyGroupAlreadyExists e) {
// either reuse the existing group or retry with a suffixed unique name
} Prevention
- Generate unique group names per run (append UUID or timestamp).
- Delete fixture groups in teardown so reruns start clean.
- Check ListKeyGroups before creating with a fixed name.
When it happens
Trigger: CreateKeyGroup with a Name already taken by another group; UpdateKeyGroup renaming a group to an existing name. The scan excludes the updated group's own id, so keeping your name during update is safe.
Common situations: Re-running setup scripts without teardown, so the previous run's group persists; test fixtures with fixed names like "default-kg" colliding across test classes sharing emulator state.
Related errors
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/6ea8f8d183b189b3.
Report an issue: GitHub.