elastic/elasticsearch · critical · IllegalStateException

Can't determine OS from: ${os}

Error message

Can't determine OS from: ${os}

What it means

OS.current() throws IllegalStateException when the JVM's os.name system property does not start with 'Windows', 'Linux'/'LINUX', or 'Mac'. The Elasticsearch build only supports Windows, Linux, and macOS; any other OS (AIX, FreeBSD, Solaris, z/OS, etc.) is rejected because the build toolchain, native tooling, and distribution packaging have no code paths for it.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/OS.java:40

    public final String javaOsReference;

    OS(String javaOsReference) {
        // This constructor is intentionally empty, but it can be used to set up any necessary state.
        this.javaOsReference = javaOsReference;
    }

    public static OS current() {
        String os = System.getProperty("os.name", "");
        if (os.startsWith("Windows")) {
            return OS.WINDOWS;
        }
        if (os.startsWith("Linux") || os.startsWith("LINUX")) {
            return OS.LINUX;
        }
        if (os.startsWith("Mac")) {
            return OS.MAC;
        }
        throw new IllegalStateException("Can't determine OS from: " + os);
    }

    public static class Conditional<T> {

        private final Map<OS, Supplier<T>> conditions = new EnumMap<>(OS.class);

        public Conditional<T> onWindows(Supplier<T> supplier) {
            conditions.put(WINDOWS, supplier);
            return this;
        }

        public Conditional<T> onLinux(Supplier<T> supplier) {
            conditions.put(LINUX, supplier);
            return this;
        }

        public Conditional<T> onMac(Supplier<T> supplier) {
            conditions.put(MAC, supplier);

View on GitHub (pinned to db6a809a66)

Solutions

  1. Run the build on a supported OS: Linux, macOS, or Windows.
  2. If on a supported OS, check System.getProperty('os.name') — a custom JVM or launcher may be reporting an unexpected value.
  3. For CI, use a standard Linux or macOS image.
  4. If you must build on an unsupported OS, you are on your own; consider cross-building in a supported container.
Defensive patterns

Strategy: validation

Validate before calling

String osName = System.getProperty("os.name", "");
if (!osName.startsWith("Windows") && !osName.startsWith("Linux") && !osName.startsWith("LINUX") && !osName.startsWith("Mac")) {
    throw new IllegalStateException("Unsupported os.name: " + osName + "; use Linux, macOS, or Windows");
}

Prevention

When it happens

Trigger: Any code path that calls OS.current() (directly or via OS.conditional().supply(), which internally calls current()). This runs eagerly at class-load for CURRENT_PLATFORM in ElasticsearchDistribution and is hit broadly across build-tools.

Common situations: Running the Elasticsearch build on an unsupported OS (FreeBSD, AIX, SmartOS); a container or CI image reporting an unexpected os.name; a JVM that returns a non-standard os.name string (rare); running under a compatibility layer that masks the OS name.

Related errors


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