floci-io/floci · error · AwsException
ValidationException
ValidationException
Error message
Invalid certificate: " + e.getMessage()
What it means
ACM ValidationException (HTTP 400) thrown by AcmService.importCertificate when the PEM certificate body cannot be parsed (certificateGenerator.parseCertificate) or fails validation (validateCertificate). The underlying parser message is appended, so the exact JCA failure (e.g. 'could not be parsed', expiry) is visible.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/acm/AcmService.java:334
}
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);
} catch (Exception e) {
throw new AwsException("ValidationException", "Invalid certificate: " + e.getMessage(), 400);
}
// Parse and validate private key
try {
certificateGenerator.parsePrivateKey(privateKeyPem);
} catch (Exception e) {
throw new AwsException("ValidationException", "Invalid private key: " + e.getMessage(), 400);
}
if (tags != null) {
validateTags(tags);
}
String certId;
String arn;
if (existingArn != null && !existingArn.isEmpty()) {
// Re-importView on GitHub (pinned to 62ff490619)
Solutions
- Validate the PEM locally first: openssl x509 -in cert.pem -noout -text — if openssl cannot read it, neither can Floci
- Ensure the input is a PEM block: -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- with intact Base64 body and newlines
- Check you passed the leaf certificate in certificatePem, not the private key or chain (chain goes in certificateChain)
- If validateCertificate rejects a parseable cert (e.g. expired), generate a fresh cert or adjust the test fixture
Example fix
// before: DER bytes or mangled PEM
byte[] der = Files.readAllBytes(Path.of("cert.der"));
acm.importCertificate(r -> r.certificatePem(new String(der, StandardCharsets.ISO_8859_1)));
// after: convert to PEM and import
String pem = "-----BEGIN CERTIFICATE-----\n" +
Base64.getMimeEncoder().encodeToString(der).replaceAll("(.{64})", "$1\n") + "\n-----END CERTIFICATE-----\n";
acm.importCertificate(r -> r.certificatePem(pem)); Defensive patterns
Strategy: validation
Validate before calling
openssl x509 -in cert.pem -noout > /dev/null && echo OK # gate before import
Type guard
private static boolean isPemCertificate(String pem) {
return pem != null && pem.contains("-----BEGIN CERTIFICATE-----")
&& pem.contains("-----END CERTIFICATE-----");
} Try / catch
try {
acm.importCertificate(r -> r.certificatePem(pem).privateKey(key));
} catch (ValidationException e) {
if (e.getMessage().contains("Invalid certificate")) { /* re-check PEM fenceposts, regenerate */ }
} Prevention
- Always gate PEM inputs with openssl x509/pkey -noout checks before importing
- Keep cert, key, and chain in clearly named files so they never get swapped
- Move PEMs through systems as single-line Base64 and re-wrap locally to protect newlines
When it happens
Trigger: acm.importCertificate with a CertificatePem that is not a valid PEM X.509 block: wrong header/footer, Windows line endings mangled through a lossy channel, a chain pasted into the certificate field, Base64 (DER) bytes instead of PEM, or a certificate rejected by validateCertificate (e.g. expired).
Common situations: Copy-pasting certs from docs/secrets losing newlines; passing the private key or CA bundle in the certificate parameter; loading files with Files.readString on binary DER; environment differences where a trailing newline is stripped.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- InvalidNextTokenException
- IdempotencyException
- ResourceInUseException
- TooManyTagsException
- BadRequestException
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/3a1a1449f175fc2c.
Report an issue: GitHub.