apache/druid · error · UnsupportedOperationException

Cannot determine maxDirectMemory from

Error message

Cannot determine maxDirectMemory from [%s]

What it means

Thrown by RuntimeInfo.getDirectMemorySizeBytes when the reflective call jdk.internal.misc.VM.maxDirectMemory() returns null or a non-Number object. Druid uses reflection into JDK internals to read -XX:MaxDirectMemorySize, and this UOE indicates the JVM answered in an unexpected shape.

Solutions

  1. Run Druid on a supported OpenJDK/HotSpot JDK build
  2. Set -XX:MaxDirectMemorySize explicitly so the VM field is populated
  3. Check druid.processing.buffer.directSize / related config to avoid relying on runtime detection
  4. Upgrade the JDK to a version where jdk.internal.misc.VM.maxDirectMemory() returns a Number

Example fix

// before (startup)
java -Xmx4g ...
// after
java -Xmx4g -XX:MaxDirectMemorySize=4g ...
Defensive patterns

Strategy: try-catch

Validate before calling

Object v;
try {
  Class<?> vm = Class.forName("jdk.internal.misc.VM");
  v = vm.getMethod("maxDirectMemory").invoke(null);
} catch (Exception e) { v = null; }
if (!(v instanceof Number)) {
  // fall back to -XX:MaxDirectMemorySize parsing or config
}

Type guard

boolean directMemoryKnown() {
  try {
    Object o = Class.forName("jdk.internal.misc.VM").getMethod("maxDirectMemory").invoke(null);
    return o instanceof Number;
  } catch (Exception e) { return false; }
}

Try / catch

try {
  long direct = runtimeInfo.getMaxDirectMemory();
} catch (UnsupportedOperationException e) {
  long direct = parseFromArgs("-XX:MaxDirectMemorySize"); // fallback
}

Prevention

When it happens

Trigger: Calling maxDirectMemory()/getDirectMemorySizeBytes() (directly or via callers such as buffer initialization or MiddleManager tuning) on a JVM where jdk.internal.misc.VM exists but maxDirectMemory() yields null or a non-numeric value - e.g. non-HotSpot/OpenJDK JVMs, exotic JDK builds, or heavily patched runtimes.

Common situations: Running Druid on unsupported JVMs (IBM J9, older forks), custom JDK builds where the internal VM class behaves differently, or reflection restrictions altering behavior.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

  public long getTotalHeapSizeBytes()
  {
    return Runtime.getRuntime().totalMemory();
  }

  public long getFreeHeapSizeBytes()
  {
    return Runtime.getRuntime().freeMemory();
  }

  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)