spring-projects/spring-boot · error · IllegalStateException

Error creating KeyStore: {}

Error message

Error creating KeyStore: {}

What it means

The outer catch in KeyStoreFactory.create handles GeneralSecurityException | IOException from every setup-phase step: getKeyStore() (KeyStore.getInstance of the default type, load(null)), Files.readString(certPath), PemCertificateParser.parse(certificateText), and getPrivateKey(keyPath). It is the catch-all for any failure before addCertificates runs; the wrapped message is the underlying exception's getMessage().

Source

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

	 * @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);
			return PemPrivateKeyParser.parse(text);
		}
		return null;
	}

View on GitHub (pinned to 270dfe353f)

Solutions

  1. Confirm the cert file exists and is readable: `ls -l <certPath>` and `openssl x509 -in <certPath> -noout`.
  2. On a custom JRE, ensure the default keystore type is available (do not exclude the PKCS12 provider).
  3. Validate the PEM is a real certificate before invoking the build.
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the cert file before calling KeyStoreFactory
if (!Files.exists(certPath) || !Files.isReadable(certPath)) {
    throw new IllegalArgumentException("Certificate file missing or unreadable: " + certPath);
}
// Validate it parses as X.509 PEM
try {
    PemCertificateParser.parse(Files.readString(certPath));
} catch (RuntimeException e) {
    throw new IllegalArgumentException("Invalid certificate at " + certPath + ": " + e.getMessage(), e);
}

Try / catch

try {
    KeyStoreFactory.create(certPath, keyPath, alias);
} catch (IllegalStateException ex) {
    if (ex.getMessage().startsWith("Error creating KeyStore")) {
        Throwable c = ex.getCause();
        // branch on IOException (file) vs GeneralSecurityException (crypto/JRE)
    }
    throw ex;
}

Prevention

When it happens

Trigger: Any of: certPath missing or unreadable (IOException from Files.readString); KeyStore.getInstance(KeyStore.getDefaultType()) fails (no provider, stripped JRE); keyStore.load(null) fails; PemCertificateParser.parse throws IllegalStateException (propagates as cause since it is a RuntimeException, not caught by the GeneralSecurityException|IOException catch — it would escape this catch); getPrivateKey IO failure.

Common situations: certPath points to a non-existent or unreadable file; running on a custom jlink runtime whose default keystore type (PKCS12 on modern JDKs) is unavailable; PEM cert file is empty or corrupted.

Related errors


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