floci-io/floci · error · AwsException
PublicKeyAlreadyExists
PublicKeyAlreadyExists
Error message
A public key with this caller reference already exists.
What it means
CloudFrontService.createPublicKey throws PublicKeyAlreadyExists (HTTP 409) when any stored public key already carries the same CallerReference. CallerReference is CloudFront's idempotency token for key creation, and this emulator treats a reused token as a conflict rather than returning the original resource.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/cloudfront/CloudFrontService.java:930
copy.setConfig(primary.getConfig());
if (copy.getConfig() != null) {
copy.getConfig().setCallerReference(callerReference);
copy.getConfig().setStaging(true);
}
return createDistribution(copy, tags);
}
// ── Public Keys ───────────────────────────────────────────────────────────
public synchronized PublicKey createPublicKey(PublicKey key) {
validatePublicKey(key);
boolean duplicateCallerReference =
publicKeyStore.scan(existing -> true).stream()
.anyMatch(existing -> Objects.equals(
existing.getCallerReference(),
key.getCallerReference()));
if (duplicateCallerReference) {
throw new AwsException(
"PublicKeyAlreadyExists",
"A public key with this caller reference already exists.",
409);
}
key.setId(UUID.randomUUID().toString());
key.setCreatedTime(Instant.now());
key.setEtag(UUID.randomUUID().toString());
publicKeyStore.put(key.getId(), key);
return key;
}
public PublicKey getPublicKey(String id) {
return publicKeyStore.get(id).orElseThrow(() ->
new AwsException("NoSuchPublicKey", "The specified public key does not exist.", 404));
}
public synchronized PublicKey updatePublicKey(String id, String ifMatch, PublicKey updated) {
PublicKey existing = getPublicKey(id);View on GitHub (pinned to 62ff490619)
Solutions
- Generate a fresh unique CallerReference (UUID) for every CreatePublicKey call.
- If this is a retry after an uncertain failure, first check ListPublicKeys/GetPublicKey for the earlier creation before re-submitting.
- Parameterize fixtures so each test run mints its own token instead of reusing a constant.
Example fix
// before
key.setCallerReference("fixed-token");
createPublicKey(key); // ok
createPublicKey(key); // 409 PublicKeyAlreadyExists
// after
key.setCallerReference(UUID.randomUUID().toString());
createPublicKey(key); Defensive patterns
Strategy: validation
Validate before calling
boolean callerReferenceInUse(CloudFrontClient client, String ref) {
return client.listPublicKeys(r -> r.build()).publicKeyList().items().stream()
.anyMatch(k -> ref.equals(k.callerReference()));
}
// before create:
if (callerReferenceInUse(client, ref)) throw new IllegalStateException("caller reference already used"); Try / catch
try {
return client.createPublicKey(r -> r.publicKeyConfig(cfg));
} catch (PublicKeyAlreadyExists e) {
// this caller reference already created a key; look it up and reuse it
return client.listPublicKeys(r -> r.build()).publicKeyList().items().stream()
.filter(k -> ref.equals(k.callerReference())).findFirst()
.orElseThrow(() -> e);
} Prevention
- Mint a fresh UUID CallerReference for every create call.
- On retry after a network error, check whether the first attempt already succeeded.
- Never hardcode caller references in shared fixtures.
When it happens
Trigger: CreatePublicKey twice with the same CallerReference string — e.g. a fixed token like "key-1" hardcoded in config, or a retry after a timeout that resends the same token after the first create actually succeeded.
Common situations: Hardcoded CallerReferences in templates or test fixtures; retries of flaky requests where the first attempt succeeded; copy-pasted JSON payloads between environments pointed at the same emulator instance.
Related errors
- PublicKeyInUse
- PreconditionFailed
- CannotChangeImmutablePublicKeyFields
- ResourceInUse
- KeyGroupAlreadyExists
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/f18d625c86d428b3.
Report an issue: GitHub.