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

  1. Publish a SHA-512 checksum file at <plugin-url>.sha512 containing `<hash> <filename>`.
  2. For custom non-official plugins, a `.sha1` fallback is supported (deprecated) — generate it alongside the zip.
  3. 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

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.