elastic/elasticsearch · error · IllegalStateException
No read-only compatible version found.
Error message
No read-only compatible version found.
What it means
Thrown by BwcVersions.withLatestReadOnlyIndexCompatible when getReadOnlyIndexCompatible() returns null or an empty list. Lucene can read indices from N-2 majors; this fires when no version two majors below the current one is registered in the parsed version set.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/BwcVersions.java:216
}
public List<Version> getReleased() {
return versions.stream()
.filter(v -> v.getMajor() >= currentVersion.getMajor() - 1)
.filter(v -> unreleased.containsKey(v) == false)
.toList();
}
public List<Version> getReadOnlyIndexCompatible() {
// Lucene can read indices in version N-2
int compatibleMajor = currentVersion.getMajor() - 2;
return versions.stream().filter(v -> v.getMajor() == compatibleMajor).sorted(Comparator.naturalOrder()).toList();
}
public void withLatestReadOnlyIndexCompatible(Consumer<Version> versionAction) {
var compatibleVersions = getReadOnlyIndexCompatible();
if (compatibleVersions == null || compatibleVersions.isEmpty()) {
throw new IllegalStateException("No read-only compatible version found.");
}
versionAction.accept(compatibleVersions.getLast());
}
/**
* Return versions of Elasticsearch which are index compatible with the current version.
*/
public List<Version> getIndexCompatible() {
return versions.stream().filter(v -> v.getMajor() >= (currentVersion.getMajor() - 1)).toList();
}
public void withIndexCompatible(BiConsumer<Version, String> versionAction) {
getIndexCompatible().forEach(v -> versionAction.accept(v, "v" + v.toString()));
}
public void withIndexCompatible(Predicate<Version> filter, BiConsumer<Version, String> versionAction) {
getIndexCompatible().stream().filter(filter).forEach(v -> versionAction.accept(v, "v" + v.toString()));
}View on GitHub (pinned to db6a809a66)
Solutions
- Ensure N-2 major versions are present in Version.java so the read-only-compatible set is non-empty.
- Verify version parsing returned the full historical list (see error 130 causes).
- Confirm the current major is correctly configured in build properties.
Defensive patterns
Strategy: validation
Validate before calling
List<Version> compatible = getReadOnlyIndexCompatible();
if (compatible == null || compatible.isEmpty()) {
throw new IllegalStateException("No read-only compatible version found.");
} Prevention
- Ensure Version.java includes N-2 major versions before relying on read-only compat checks.
- Validate the parsed version list is complete (see error 130).
- Guard callers of withLatestReadOnlyIndexCompatible against an empty compatible set.
When it happens
Trigger: The current major is so new (or the version list is so truncated) that no N-2 major version exists in the parsed list, so getReadOnlyIndexCompatible filters down to nothing.
Common situations: Very early in a new major cycle before N-2 versions are populated; version parsing returned a partial list; corrupt or truncated Version.java.
Related errors
- System property 'bwc.throttle.maxParallelUsages' must be >=
- System property 'bwc.throttle.maxParallelUsages' must be an
- Cannot read java properties file.
- Could not parse any versions
- Parsed versions latest version does not match the one config
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/fbc9d182188c144b.
Report an issue: GitHub.