spring-projects/spring-boot · error · IllegalStateException

Error adding certificates to KeyStore: {}

Error message

Error adding certificates to KeyStore: {}

What it means

KeyStoreFactory.addCertificates calls keyStore.setKeyEntry(alias, privateKey, NO_PASSWORD, certificates) when a private key is present, or keyStore.setCertificateEntry(alias+'-'+i, cert) otherwise. A KeyStoreException means the keystore rejected the entry. The keystore itself was freshly created and loaded empty by getKeyStore(), so the failure is almost always about the cert/key combination rather than keystore state.

Source

Thrown at buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/KeyStoreFactory.java:63

	/**
	 * Create a new {@link KeyStore} populated with the certificate stored at the
	 * specified file path and an optional private key.
	 * @param certPath the path to the certificate authority file
	 * @param keyPath the path to the private file
	 * @param alias the alias to use for KeyStore entries
	 * @return the {@code KeyStore}
	 */
	static KeyStore create(Path certPath, @Nullable Path keyPath, String alias) {
		try {
			KeyStore keyStore = getKeyStore();
			String certificateText = Files.readString(certPath);
			List<X509Certificate> certificates = PemCertificateParser.parse(certificateText);
			PrivateKey privateKey = getPrivateKey(keyPath);
			try {
				addCertificates(keyStore, certificates.toArray(X509Certificate[]::new), privateKey, alias);
			}
			catch (KeyStoreException ex) {
				throw new IllegalStateException("Error adding certificates to KeyStore: " + ex.getMessage(), ex);
			}
			return keyStore;
		}
		catch (GeneralSecurityException | IOException ex) {
			throw new IllegalStateException("Error creating KeyStore: " + ex.getMessage(), ex);
		}
	}

	private static KeyStore getKeyStore()
			throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
		KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
		keyStore.load(null);
		return keyStore;
	}

	private static @Nullable PrivateKey getPrivateKey(@Nullable Path path) throws IOException {
		if (path != null && Files.exists(path)) {
			String text = Files.readString(path);

View on GitHub (pinned to 270dfe353f)

Solutions

  1. Verify key/cert match: for RSA compare `openssl x509 -noout -modulus -in cert.pem` with `openssl rsa -noout -modulus -in key.pem`; for EC/Ed25519 compare public key fingerprints via `openssl pkey -pubout -in key.pem` vs `openssl x509 -pubkey -noout -in cert.pem`.
  2. Re-issue the certificate from the same private key, or supply a matching key.
  3. Omit keyPath if you only need to trust a CA cert (no private key).
Defensive patterns

Strategy: validation

Validate before calling

// Verify private key and certificate share a public key before calling KeyStoreFactory
PublicKey certPub = CertificateFactory.getInstance("X.509")
        .generateCertificate(Files.newInputStream(certPath)).getPublicKey();
if (keyPath != null && Files.exists(keyPath)) {
    PrivateKey pk = PemPrivateKeyParser.parse(Files.readString(keyPath));
    if (!Arrays.equals(pk.getEncoded(), /* derive */ pk.getEncoded())
            && !certPub.getAlgorithm().equals(pk.getAlgorithm())) {
        throw new IllegalArgumentException("Certificate and private key do not match.");
    }
}

Try / catch

try {
    KeyStoreFactory.create(certPath, keyPath, alias);
} catch (IllegalStateException ex) {
    if (ex.getCause() instanceof KeyStoreException
            && ex.getMessage().startsWith("Error adding certificates to KeyStore")) {
        // hint: verify key/cert match with openssl
    }
    throw ex;
}

Prevention

When it happens

Trigger: addCertificates at lines 90 or 94 throws KeyStoreException: private key does not match the certificate chain (key/cert from different keypairs); alias already present with an incompatible entry type; certificate chain is empty when a privateKey is supplied.

Common situations: Supplying a certificate PEM that was issued for a different private key than the one in keyPath; mixing CA certs with a leaf cert from a different keypair; pointing certPath and keyPath at mismatched files.

Understand the failure class

Related errors


AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11). Data as JSON: /api/errors/7d2abcc66be3d91c. Report an issue: GitHub.