elastic/elasticsearch · error · RuntimeException
Unexpected md5 response from [{}]
Error message
Unexpected md5 response from [{}] What it means
Thrown by IpinfoDownload.checksum() after fetching the checksums JSON from Ipinfo. The JSON's checksums.md5 value must match MD5_CHECKSUM_PATTERN = (\w{32}); a missing md5 field, a null, or any non-32-hex value triggers this. It is a RuntimeException propagating out of checksum() and aborting the download.
Source
Thrown at modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/EnterpriseGeoIpDownloader.java:595
return Strings.format(endpointPattern, internalName, suffix);
}
@Override
public Checksum checksum() throws IOException {
final String checksumJsonUrl = this.url("mmdb/checksums"); // a minor abuse of the idea of a 'suffix', :shrug:
byte[] data = httpClient.getBytes(auth.get(), checksumJsonUrl); // this throws if the auth is bad
Map<String, Object> checksums;
try (XContentParser parser = XContentType.JSON.xContent().createParser(XContentParserConfiguration.EMPTY, data)) {
checksums = parser.map();
}
@SuppressWarnings("unchecked")
String md5 = ((Map<String, String>) checksums.get("checksums")).get("md5");
logger.trace("checksum was [{}]", md5);
var matcher = MD5_CHECKSUM_PATTERN.matcher(md5);
boolean match = matcher.matches();
if (match == false) {
throw new RuntimeException("Unexpected md5 response from [" + checksumJsonUrl + "]");
}
return Checksum.md5(md5);
}
@Override
public CheckedSupplier<InputStream, IOException> download() {
final String mmdbUrl = this.url("mmdb");
return () -> httpClient.get(auth.get(), mmdbUrl);
}
@Override
public void close() throws IOException {
if (auth != null) auth.close();
}
}
interface ProviderDownload extends Closeable {
// note: buildCredentials and url are inherently just implementation details of checksum() and download(),View on GitHub (pinned to db6a809a66)
Solutions
- Manually fetch the checksumJsonUrl with the configured token to inspect the response body and confirm an md5 field is present.
- Validate/regenerate the Ipinfo token in secure settings.
- Confirm the Ipinfo endpoint base URL is correct and not redirected to a generic host.
- If Ipinfo changed the schema, update MD5_CHECKSUM_PATTERN or the JSON field extraction (code change).
Defensive patterns
Strategy: try-catch
Try / catch
try {
Checksum cs = ipinfoDownload.checksum();
} catch (RuntimeException e) {
// message starts with "Unexpected md5 response from"
// fetch the checksumJsonUrl manually, verify md5 field present, fix token/endpoint, retry next schedule
logger.error("ipinfo md5 body unparseable for [{}]", checksumJsonUrl, e);
} Prevention
- Keep the Ipinfo token valid.
- Do not route Ipinfo traffic through a proxy that rewrites the JSON body.
- If Ipinfo changes schema, update MD5_CHECKSUM_PATTERN or the field path.
- Log the raw JSON body on failure for diagnostics.
When it happens
Trigger: IpinfoDownload.checksum() -> httpClient.getBytes(auth, checksumJsonUrl) -> parse JSON -> extract checksums.md5 -> matcher.matches() == false. Common when the token is wrong and Ipinfo returns a 200 JSON error with no md5, or when Ipinfo changes its checksum schema.
Common situations: Invalid/expired Ipinfo token returning a JSON error body; Ipinfo schema change; corporate proxy returning an HTML error that fails JSON parsing earlier or yields a non-md5 string; NPE-style issue if md5 is null (matcher would NPE before this line in some cases).
Related errors
- Unexpected sha256 response from [{}]
- checksum mismatch, expected [{}], actual [{}]
- md5 checksum mismatch, expected [{}], actual [{}]
- too many redirects connection to [{}]
- {} not found
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/3a93215f2fb8093f.
Report an issue: GitHub.