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
- Run Druid on a supported OpenJDK/HotSpot JDK build
- Set -XX:MaxDirectMemorySize explicitly so the VM field is populated
- Check druid.processing.buffer.directSize / related config to avoid relying on runtime detection
- 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
- Run on a supported HotSpot/OpenJDK build
- Set -XX:MaxDirectMemorySize explicitly at startup
- Prefer explicit Druid processing buffer config over runtime introspection
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
- No VM class, cannot do memory check.
- Unmapping is not supported on this platform, because…
- VM.maxDirectMemory doesn't exist, cannot do memory check.
- CLEANER_NOT_SUPPORTED_EXCEPTION
- Cleaning is not support on this platform, because internal…
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)