floci-io/floci · error · AwsException
PublicKeyInUse
PublicKeyInUse
Error message
The specified public key is in use.
What it means
CloudFrontService.deletePublicKey throws PublicKeyInUse (HTTP 409) when publicKeyInUse(id) finds the key still referenced by some stored resource (for example a distribution configuration referencing it). CloudFront refuses to delete keys that configurations depend on, and the emulator mirrors that guard before removing the key from the store.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/cloudfront/CloudFrontService.java:983
400);
}
updated.setId(id);
updated.setCreatedTime(existing.getCreatedTime());
updated.setEtag(UUID.randomUUID().toString());
publicKeyStore.put(id, updated);
return updated;
}
public synchronized void deletePublicKey(String id, String ifMatch) {
PublicKey existing = getPublicKey(id);
if (!existing.getEtag().equals(ifMatch)) {
throw new AwsException(
"PreconditionFailed",
"The precondition in one or more request-header fields evaluated to false.",
412);
}
if (publicKeyInUse(id)) {
throw new AwsException(
"PublicKeyInUse", "The specified public key is in use.", 409);
}
publicKeyStore.delete(id);
}
public List<PublicKey> listPublicKeys(String marker, int maxItems) {
List<PublicKey> all = new ArrayList<>(publicKeyStore.scan(k -> true));
all.sort((a, b) -> a.getId().compareTo(b.getId()));
return paginate(all, marker, maxItems, PublicKey::getId);
}
/**
* Resolves the PEM public key for a {@code Key-Pair-Id} used to sign a request, but only when that
* public key is a member of one of the supplied key groups. Returns {@code null} when the key is
* unknown or is not a member of any of those groups — i.e. it is not a trusted signer.
*/
public String trustedPublicKeyPem(String keyPairId, List<String> keyGroupIds) {
if (keyPairId == null || keyGroupIds == null || keyGroupIds.isEmpty()) {View on GitHub (pinned to 62ff490619)
Solutions
- Delete or update every distribution that references the key first, then delete the key.
- Before deleting, scan ListDistributions for configurations referencing the key id and clean them up.
- Make teardown order reverse of creation: distributions → key groups → public keys.
Example fix
// before
deletePublicKey(keyId); // 409 while a distribution references it
// after
for (Distribution d : distributionsReferencing(keyId)) {
deleteDistribution(d.getId());
}
deletePublicKey(keyId); Defensive patterns
Strategy: try-catch
Validate before calling
boolean publicKeyReferenced(CloudFrontClient client, String keyId) {
return client.listDistributions(r -> r.build()).distributionList().items().stream()
.anyMatch(d -> distributionReferencesKey(d, keyId));
} Try / catch
try {
client.deletePublicKey(r -> r.id(keyId).ifMatch(etag));
} catch (PublicKeyInUse e) {
// find and remove/ delete referencing distributions, then retry delete with a fresh etag
} Prevention
- Delete distributions (or strip their key references) before deleting the key.
- Use reverse-creation-order teardown in tests.
- Run against a clean state or unique names per run to avoid stale references.
When it happens
Trigger: DeletePublicKey while any distribution's config still references the key id — e.g. deleting immediately after CreateDistribution succeeded, or after re-creating a distribution that re-attached the key.
Common situations: Teardown deleting resources in creation order (key before distribution); tests that recreate distributions between runs; forgetting that updated distributions may reintroduce references.
Related errors
- PublicKeyAlreadyExists
- ResourceInUse
- PreconditionFailed
- CannotChangeImmutablePublicKeyFields
- KeyGroupAlreadyExists
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/2950f86fbfc1bb6a.
Report an issue: GitHub.