elastic/elasticsearch · critical · IllegalStateException
key id [{}] does not match expected key id [{}]
Error message
key id [{}] does not match expected key id [{}] What it means
IllegalStateException (unchecked) thrown by PgpSignatureVerifier.verifySignature when the key ID embedded in the detached `.asc` signature does not equal the expected `publicKeyId`. This is a trust/integrity guard: the signature must have been produced by Elastic's published signing key, and a mismatch means either the signature file is for a different key or the expected key id is wrong. There is no exit code — it propagates as a runtime exception.
Source
Thrown at distribution/tools/plugin-cli/bc/src/main/java/org/elasticsearch/plugins/cli/bc/PgpSignatureVerifier.java:61
String publicKeyId,
String urlString,
InputStream pluginZipInputStream,
InputStream ascInputStream,
InputStream publicKeyInputStream
) throws IOException {
try (
InputStream fin = pluginZipInputStream;
InputStream sin = ascInputStream;
InputStream ain = new ArmoredInputStream(publicKeyInputStream) // input stream to the public key in ASCII-Armor format (RFC4880)
) {
final JcaPGPObjectFactory factory = new JcaPGPObjectFactory(PGPUtil.getDecoderStream(sin));
final PGPSignature signature = ((PGPSignatureList) factory.nextObject()).get(0);
// validate the signature has key ID matching our public key ID
final String keyId = Long.toHexString(signature.getKeyID()).toUpperCase(Locale.ROOT);
if (publicKeyId.equals(keyId) == false) {
throw new IllegalStateException("key id [" + keyId + "] does not match expected key id [" + publicKeyId + "]");
}
// compute the signature of the downloaded plugin zip
computeSignatureForDownloadedPlugin(fin, ain, signature);
// finally we verify the signature of the downloaded plugin zip matches the expected signature
if (signature.verify() == false) {
throw new IllegalStateException("signature verification for [" + urlString + "] failed");
}
} catch (PGPException e) {
throw new IOException("PGP exception during signature verification for [" + urlString + "]", e);
}
}
private static void computeSignatureForDownloadedPlugin(InputStream fin, InputStream ain, PGPSignature signature) throws PGPException,
IOException {
final PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection(ain, new JcaKeyFingerprintCalculator());
final PGPPublicKey key = collection.getPublicKey(signature.getKeyID());View on GitHub (pinned to db6a809a66)
Solutions
- Update to a build that knows the current Elastic signing key id (upgrade the distribution), or supply the correct public key.
- Confirm the `.asc` and the ZIP come from the same release (re-download both from the official source).
- For third-party plugins, install from the author's documented key, not Elastic's.
- If the key rotation is legitimate and verified, update the configured `publicKeyId` accordingly.
Defensive patterns
Strategy: try-catch
Try / catch
try {
PgpSignatureVerifier.verifySignature(publicKeyId, url, zip, asc, pubKey);
} catch (IllegalStateException | IOException e) {
// treat as untrusted artifact: abort install, do not fall back to unsigned
throw e;
} Prevention
- Always download plugins and their `.asc` from the official Elastic source in lockstep.
- Keep the bundled Elastic signing key current by staying on a supported build.
- Never downgrade trust on failure — investigate the key-id mismatch before proceeding.
When it happens
Trigger: Installing a plugin whose `.asc` was signed by a different key than the one bundled/expected; a stale `publicKeyId` after Elastic rotated signing keys; a man-in-the-middle or tampered artifact replacing the signature; mismatched `--plugin-certificate`/key configuration.
Common situations: Elastic rotating its plugin signing key between versions; third-party plugins signed by their own key; mirrors/CDNs serving a mismatched `.asc`.
Related errors
- signature verification for [{}] failed
- PGP exception during signature verification for [{}]
- 64
- Cannot combine trust configurations [{}]
- failed to initialize a TrustManager for the system keystore
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/8e1541b3fe91898b.
Report an issue: GitHub.