floci-io/floci · error · AwsException
ResourceInUseException
ResourceInUseException
Error message
Certificate " + certificateArn + " is in use by: " + String.join(", ", cert.getInUseBy()) What it means
ACM ResourceInUseException (HTTP 409) thrown by AcmService.deleteCertificate when the certificate's inUseBy list is non-empty. Floci tracks which resources (e.g. load balancers, CloudFront distributions) reference a certificate; ACM refuses deletion while the certificate is attached, mirroring AWS behavior.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/acm/AcmService.java:314
if (token == null || token.isEmpty()) return null;
try {
String json = new String(Base64.getDecoder().decode(token), StandardCharsets.UTF_8);
// Simple JSON parsing without Jackson dependency in this method
int start = json.indexOf("\"lastArn\":\"") + 11;
int end = json.indexOf("\"", start);
return json.substring(start, end);
} catch (Exception e) {
throw new AwsException("InvalidNextTokenException", "Invalid pagination token", 400);
}
}
// ============ DeleteCertificate ============
public void deleteCertificate(String certificateArn, String region) {
Certificate cert = getCertificateByArn(certificateArn, region);
if (cert.getInUseBy() != null && !cert.getInUseBy().isEmpty()) {
throw new AwsException("ResourceInUseException",
"Certificate " + certificateArn + " is in use by: " + String.join(", ", cert.getInUseBy()), 409);
}
String storageKey = regionKey(region, cert.extractCertificateId());
store.delete(storageKey);
LOG.infov("Deleted certificate: {0}", certificateArn);
}
// ============ ImportCertificate ============
public Certificate importCertificate(String certificatePem, String privateKeyPem, String chainPem,
String existingArn, Map<String, String> tags, String region) {
logSecurityWarningOnce();
// Parse and validate certificate
X509Certificate x509Cert;
try {
x509Cert = certificateGenerator.parseCertificate(certificatePem);
certificateGenerator.validateCertificate(x509Cert);View on GitHub (pinned to 62ff490619)
Solutions
- Read the error message — it lists exactly which resources hold the certificate
- Delete or detach the dependent resource(s) first (delete the ALB/CloudFront/stack), then retry deleteCertificate
- In CloudFormation scenarios, delete the stack that owns the certificate rather than calling deleteCertificate directly
- Make cleanup scripts order-independent: loop until deletions succeed or tolerate 409 with a retry budget
Example fix
// before acm.deleteCertificate(r -> r.certificateArn(arn)); // after: release dependents first, then delete // 1) delete stack / listener that references arn // 2) optionally confirm: describeCertificate(arn).inUseBy() is empty acm.deleteCertificate(r -> r.certificateArn(arn));
Defensive patterns
Strategy: try-catch
Validate before calling
var cert = acm.describeCertificate(r -> r.certificateArn(arn)).certificate();
if (cert.hasInUseBy() && !cert.inUseBy().isEmpty()) {
throw new IllegalStateException("certificate still in use by " + cert.inUseBy());
} Try / catch
try {
acm.deleteCertificate(r -> r.certificateArn(arn));
} catch (ResourceInUseException e) {
// parse the holders from e.getMessage(), delete them first, then retry once
} Prevention
- Order teardown: consumers before certificates
- In CloudFormation, delete the owning stack instead of calling deleteCertificate directly
- Make cleanup scripts tolerate 409 and re-run rather than aborting
When it happens
Trigger: acm.deleteCertificate on an ARN whose Certificate.inUseBy contains at least one entry — i.e. some other emulated resource (ALB listener, CloudFront alias, API Gateway domain) still references the cert. The message enumerates the exact holders.
Common situations: Test teardown deleting certificates before the stacks that use them; CloudFormation stacks still ACTIVE referencing the cert via Fn::GetAtt/Ref; retrying a cleanup script out of order after a partial failure.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/efa1721d8ea62f43.
Report an issue: GitHub.