elastic/elasticsearch · error · RuntimeException

Unexpected sha256 response from [{}]

Error message

Unexpected sha256 response from [{}]

What it means

Thrown by MaxmindDownload.checksum() after fetching the <endpoint>/tar.gz.sha256 URL. The body must fully match SHA256_CHECKSUM_PATTERN = (\w{64})\s\s(.*); anything else (an error page, a reformatted checksum line, an empty body) is treated as an unexpected provider response. Wrapped in a RuntimeException, it propagates out of checksum() and aborts the download attempt.

Source

Thrown at modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/EnterpriseGeoIpDownloader.java:500

            if (endpointPattern.endsWith("/") == false) {
                endpointPattern += "/";
            }
            endpointPattern += "%s/download?suffix=%s";

            // at this point the pattern looks like this (in the default case):
            // https://download.maxmind.com/geoip/databases/%s/download?suffix=%s

            return Strings.format(endpointPattern, name, suffix);
        }

        @Override
        public Checksum checksum() throws IOException {
            final String sha256Url = this.url("tar.gz.sha256");
            var result = new String(httpClient.getBytes(auth.get(), sha256Url), StandardCharsets.UTF_8).trim(); // throws if the auth is bad
            var matcher = SHA256_CHECKSUM_PATTERN.matcher(result);
            boolean match = matcher.matches();
            if (match == false) {
                throw new RuntimeException("Unexpected sha256 response from [" + sha256Url + "]");
            }
            final String sha256 = matcher.group(1);
            return Checksum.sha256(sha256);
        }

        @Override
        public CheckedSupplier<InputStream, IOException> download() {
            final String tgzUrl = this.url("tar.gz");
            return () -> httpClient.get(auth.get(), tgzUrl);
        }

        @Override
        public void close() throws IOException {
            if (auth != null) auth.close();
        }
    }

    class IpinfoDownload implements ProviderDownload {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Manually GET the sha256 URL printed in the message using the same credentials to inspect the actual body.
  2. Validate the Maxmind license key is active and has download quota.
  3. Confirm the endpointPattern / endpoint override in settings still points at the real Maxmind download host.
  4. If Maxmind changed the delimiter, the pattern constant in EnterpriseGeoIpDownloader needs updating (code change).
Defensive patterns

Strategy: try-catch

Try / catch

try {
    Checksum cs = maxmindDownload.checksum();
} catch (RuntimeException e) {
    // message starts with "Unexpected sha256 response from"
    // fetch the URL manually, inspect the body, fix credentials/endpoint, then retry on next schedule
    logger.error("maxmind sha256 body unparseable for [{}]", sha256Url, e);
}

Prevention

When it happens

Trigger: MaxmindDownload.checksum() -> httpClient.getBytes(auth, sha256Url) -> new String(...).trim() -> matcher.matches() == false. Happens when Maxmind returns a maintenance page, a single-space-separated checksum, or an HTML auth error with HTTP 200.

Common situations: Maxmind endpoint format change; expired/invalid license key returning a 200 HTML error page; corporate proxy rewriting the body; endpointPattern misconfigured so the URL hits a generic page.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/0e184e046583b43d. Report an issue: GitHub.