{"record":{"id":"fa47d8fd9bb63be0","repo":"apache/druid","slug":"cannot-determine-maxdirectmemory-from-s","errorCode":null,"errorMessage":"Cannot determine maxDirectMemory from [%s]","messagePattern":"Cannot determine maxDirectMemory from \\[(.+?)\\]","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/utils/RuntimeInfo.java","lineNumber":57,"sourceCode":"\n  public long getTotalHeapSizeBytes()\n  {\n    return Runtime.getRuntime().totalMemory();\n  }\n\n  public long getFreeHeapSizeBytes()\n  {\n    return Runtime.getRuntime().freeMemory();\n  }\n\n  public long getDirectMemorySizeBytes()\n  {\n    try {\n      Class<?> vmClass = Class.forName(\"jdk.internal.misc.VM\");\n      Object maxDirectMemoryObj = vmClass.getMethod(\"maxDirectMemory\").invoke(null);\n\n      if (maxDirectMemoryObj == null || !(maxDirectMemoryObj instanceof Number)) {\n        throw new UOE(\"Cannot determine maxDirectMemory from [%s]\", maxDirectMemoryObj);\n      } else {\n        return ((Number) maxDirectMemoryObj).longValue();\n      }\n    }\n    catch (ClassNotFoundException e) {\n      throw new UnsupportedOperationException(\"No VM class, cannot do memory check.\", e);\n    }\n    catch (NoSuchMethodException e) {\n      throw new UnsupportedOperationException(\"VM.maxDirectMemory doesn't exist, cannot do memory check.\", e);\n    }\n    catch (InvocationTargetException e) {\n      throw new UnsupportedOperationException(\"static method shouldn't throw this\", e);\n    }\n    catch (IllegalAccessException e) {\n      throw new UnsupportedOperationException(\"public method, shouldn't throw this\", e);\n    }\n  }\n}","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/utils/RuntimeInfo.java#L39-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"Running Druid on unsupported JVMs (IBM J9, older forks), custom JDK builds where the internal VM class behaves differently, or reflection restrictions altering behavior.","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"],"exampleFix":"// before (startup)\njava -Xmx4g ...\n// after\njava -Xmx4g -XX:MaxDirectMemorySize=4g ...","handlingStrategy":"try-catch","validationCode":"Object v;\ntry {\n  Class<?> vm = Class.forName(\"jdk.internal.misc.VM\");\n  v = vm.getMethod(\"maxDirectMemory\").invoke(null);\n} catch (Exception e) { v = null; }\nif (!(v instanceof Number)) {\n  // fall back to -XX:MaxDirectMemorySize parsing or config\n}","typeGuard":"boolean directMemoryKnown() {\n  try {\n    Object o = Class.forName(\"jdk.internal.misc.VM\").getMethod(\"maxDirectMemory\").invoke(null);\n    return o instanceof Number;\n  } catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n  long direct = runtimeInfo.getMaxDirectMemory();\n} catch (UnsupportedOperationException e) {\n  long direct = parseFromArgs(\"-XX:MaxDirectMemorySize\"); // fallback\n}","preventionTips":["Run on a supported HotSpot/OpenJDK build","Set -XX:MaxDirectMemorySize explicitly at startup","Prefer explicit Druid processing buffer config over runtime introspection"],"tags":["jvm","reflection","memory"],"backgroundTag":"unsupported-platform","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}