apache/druid · error · UnsupportedOperationException

VM.maxDirectMemory doesn't exist, cannot do memory check.

Error message

VM.maxDirectMemory doesn't exist, cannot do memory check.

What it means

Thrown by RuntimeInfo.getDirectMemorySizeBytes when the reflective lookup of jdk.internal.misc.VM.maxDirectMemory() throws NoSuchMethodException - the VM class exists but has no such method in this JDK build. Wrapped in UnsupportedOperationException because direct-memory introspection is unavailable.

Solutions

  1. Pin Druid to a JDK version whose internals Druid supports (check Druid's tested JDK matrix)
  2. Set -XX:MaxDirectMemorySize and rely on Druid config (druid.processing.buffer.directSize or derived settings) rather than runtime introspection
  3. Check for a newer Druid version with updated reflective lookup for your JDK

Example fix

// before (Dockerfile)
FROM ghcr.io/graalvm/jdk:latest
// after
FROM eclipse-temurin:17-jre
Defensive patterns

Strategy: try-catch

Validate before calling

boolean methodAvailable;
try {
  Class.forName("jdk.internal.misc.VM").getMethod("maxDirectMemory");
  methodAvailable = true;
} catch (ReflectiveOperationException e) { methodAvailable = false; }

Type guard

static boolean hasMaxDirectMemoryMethod() {
  try {
    Class.forName("jdk.internal.misc.VM").getMethod("maxDirectMemory");
    return true;
  } catch (ReflectiveOperationException e) { return false; }
}

Try / catch

try {
  long direct = runtimeInfo.getMaxDirectMemory();
} catch (UnsupportedOperationException e) {
  long direct = Long.getLong("druid.processing.buffer.directSize", defaultDirect);
}

Prevention

When it happens

Trigger: Calling getDirectMemorySizeBytes() (directly or via maxDirectMemory, Memory, buffer init, MM/Peon tuning) on JDK builds where the internal VM class does not declare maxDirectMemory(), e.g. some vendor JDKs,GraalVM, or future JDK releases that removed/renamed the internal API.

Common situations: Upgrading to a JDK version that reshuffled JDK-internal APIs, running on GraalVM or vendor-distinct JDKs, using a JRE image that omitted internal classes' methods.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/2e1e64359da18700. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/utils/RuntimeInfo.java:66

  }

  public long getDirectMemorySizeBytes()
  {
    try {
      Class<?> vmClass = Class.forName("jdk.internal.misc.VM");
      Object maxDirectMemoryObj = vmClass.getMethod("maxDirectMemory").invoke(null);

      if (maxDirectMemoryObj == null || !(maxDirectMemoryObj instanceof Number)) {
        throw new UOE("Cannot determine maxDirectMemory from [%s]", maxDirectMemoryObj);
      } else {
        return ((Number) maxDirectMemoryObj).longValue();
      }
    }
    catch (ClassNotFoundException e) {
      throw new UnsupportedOperationException("No VM class, cannot do memory check.", e);
    }
    catch (NoSuchMethodException e) {
      throw new UnsupportedOperationException("VM.maxDirectMemory doesn't exist, cannot do memory check.", e);
    }
    catch (InvocationTargetException e) {
      throw new UnsupportedOperationException("static method shouldn't throw this", e);
    }
    catch (IllegalAccessException e) {
      throw new UnsupportedOperationException("public method, shouldn't throw this", e);
    }
  }
}

View on GitHub (pinned to 9b90983fd2)