elastic/elasticsearch · error · UserException
74
74
Error message
Plugin checksum missing: {} What it means
Thrown after checksum resolution: the code first tries <url>.sha512, and for non-official plugins falls back to <url>.sha1 with a deprecation warning. If both are missing (checksumUrl still null), a UserException with IO_ERROR (74) is raised naming the last attempted checksum URL string.
Source
Thrown at distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/InstallPluginAction.java:582
private Path downloadAndValidate(final String urlString, final Path tmpDir, final boolean officialPlugin) throws IOException,
UserException, URISyntaxException {
Path zip = downloadZip(urlString, tmpDir);
pathsToDeleteOnShutdown.add(zip);
String checksumUrlString = urlString + ".sha512";
URL checksumUrl = openUrl(checksumUrlString);
String digestAlgo = "SHA-512";
if (checksumUrl == null && officialPlugin == false) {
// fallback to sha1, until 7.0, but with warning
terminal.println(
"Warning: sha512 not found, falling back to sha1. This behavior is deprecated and will be removed in a "
+ "future release. Please update the plugin to use a sha512 checksum."
);
checksumUrlString = urlString + ".sha1";
checksumUrl = openUrl(checksumUrlString);
digestAlgo = "SHA-1";
}
if (checksumUrl == null) {
throw new UserException(ExitCodes.IO_ERROR, "Plugin checksum missing: " + checksumUrlString);
}
final String expectedChecksum;
try (InputStream in = urlOpenStream(checksumUrl)) {
/*
* The supported format of the SHA-1 files is a single-line file containing the SHA-1. The supported format of the SHA-512 files
* is a single-line file containing the SHA-512 and the filename, separated by two spaces. For SHA-1, we verify that the hash
* matches, and that the file contains a single line. For SHA-512, we verify that the hash and the filename match, and that the
* file contains a single line.
*/
final BufferedReader checksumReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
if (digestAlgo.equals("SHA-1")) {
expectedChecksum = checksumReader.readLine();
} else {
final String checksumLine = checksumReader.readLine();
final String[] fields = checksumLine.split(" {2}");
if (officialPlugin && fields.length != 2 || officialPlugin == false && fields.length > 2) {
throw new UserException(ExitCodes.IO_ERROR, "Invalid checksum file at " + checksumUrl);
}View on GitHub (pinned to db6a809a66)
Solutions
- Publish a SHA-512 checksum file at <plugin-url>.sha512 containing `<hash> <filename>`.
- For custom non-official plugins, a `.sha1` fallback is supported (deprecated) — generate it alongside the zip.
- Ensure the host serving the zip also serves the checksum with the same path suffix and correct permissions.
Example fix
# before # server hosts myplugin.zip only # after sha512sum myplugin.zip > myplugin.zip.sha512 # serve both myplugin.zip and myplugin.zip.sha512
Defensive patterns
Strategy: validation
Validate before calling
String zipUrl = "https://host/myplugin.zip";
for (String suffix : new String[]{".sha512", ".sha1"}) {
if (!canHead(zipUrl + suffix)) {
throw new IllegalStateException("Missing checksum file at " + zipUrl + suffix);
}
} Prevention
- Always publish a `.sha512` alongside every custom plugin zip.
- Run a pre-flight HEAD request for the checksum URL in CI before invoking the installer.
When it happens
Trigger: Hosting a custom plugin zip without publishing a matching .sha512 (or .sha1) checksum file alongside it; the checksum host returns 404; proxy/network blocks the checksum request but not the zip request.
Common situations: Self-hosted/internal plugin repositories that omit checksum files; misconfigured reverse proxies stripping checksum requests.
Related errors
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/d9915edf7d8a8fdd.
Report an issue: GitHub.