elastic/elasticsearch · error · IOException
PGP exception during signature verification for [{}]
Error message
PGP exception during signature verification for [{}] What it means
IOException (checked) wrapping a `PGPException` that escaped the try block of verifySignature — i.e. a lower-level BouncyCastle/PGP failure during parsing or verification that is neither a key-id mismatch nor a simple verify=false. It is caught by `catch (PGPException e)` and rethrown with context including the URL. Common causes: malformed `.asc` file, ArmoredInputStream parse error, missing public key in the keyring, or `signature.init` failure.
Source
Thrown at distribution/tools/plugin-cli/bc/src/main/java/org/elasticsearch/plugins/cli/bc/PgpSignatureVerifier.java:72
) {
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());
signature.init(new JcaPGPContentVerifierBuilderProvider(), key);
final byte[] buffer = new byte[1024];
int read;
while ((read = fin.read(buffer)) != -1) {
signature.update(buffer, 0, read);
}
}
}
View on GitHub (pinned to db6a809a66)
Solutions
- Inspect the wrapped PGPException's message/cause to find the precise PGP failure (e.g. 'invalid header', 'unknown object').
- Re-download the `.asc` signature and confirm it is valid armored PGP (`-----BEGIN PGP SIGNATURE-----`).
- Ensure the public key input is the correct, current Elastic signing key.
- Retry with a fresh download; if behind a proxy, bypass and re-test.
Defensive patterns
Strategy: try-catch
Try / catch
try {
PgpSignatureVerifier.verifySignature(publicKeyId, url, zip, asc, pubKey);
} catch (IOException e) {
Throwable cause = e.getCause(); // PGPException
// inspect cause message; re-download .asc / public key and retry
} Prevention
- Validate the `.asc` starts with `-----BEGIN PGP SIGNATURE-----` before verifying.
- Ensure the public key ring contains the key referenced by the signature.
- Avoid proxies that return HTML error pages masquerading as `.asc`.
When it happens
Trigger: A `.asc` file that is not valid ASCII-armored PGP (corrupt or wrong format); the public key ring does not contain the key referenced by the signature; PGP library version incompatibility; truncated signature file.
Common situations: Downloading a `.asc` that is actually an HTML error page from a proxy; outdated bundled public key; partial file transfer.
Related errors
- key id [{}] does not match expected key id [{}]
- signature verification for [{}] failed
- 64
- No GPU resources available and unable to create new ones
- Can't advance to doc using {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/0ac558506b35e63b.
Report an issue: GitHub.