oracle/graal · error · GraalError
Use of %s is only supported in jargraal
Error message
Use of %s is only supported in jargraal
What it means
GraalError thrown during BenchmarkCounters initialization when -Dgraal.TimedDynamicCounters is set to a positive interval while running inside libgraal (the SVM-compiled in-process compiler library). Timed dumping relies on starting a Java Thread that periodically collects counters; libgraal's image heap/runtime does not support this, and the option is only meaningful in jargraal (JVM-embedded Java-mode Graal).
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/debug/BenchmarkCounters.java:494
throw new GraalError("invalid arguments to BenchmarkDynamicCounters: (err|out),start,end,(err|out),start,end,... (~ matches multiple digits)");
}
for (int i = 0; i < arguments.length; i += 3) {
if (arguments[i].equals("err")) {
System.setErr(new PrintStream(new BenchmarkCountersOutputStream(System.err, arguments[i + 1], arguments[i + 2])));
} else if (arguments[i].equals("out")) {
System.setOut(new PrintStream(new BenchmarkCountersOutputStream(System.out, arguments[i + 1], arguments[i + 2])));
} else {
throw new GraalError("invalid arguments to BenchmarkDynamicCounters: err|out");
}
}
enabled = true;
}
if (Options.GenericDynamicCounters.getValue(options)) {
enabled = true;
}
if (Options.TimedDynamicCounters.getValue(options) > 0) {
if (LibGraalSupport.inLibGraalRuntime()) {
throw new GraalError("Use of %s is only supported in jargraal", Options.TimedDynamicCounters.getName());
}
Thread thread = new Thread(new Runnable() {
long lastTime = System.nanoTime();
@Override
public void run() {
try (PrintStreamScope scope = getPrintStream(options)) {
while (true) { // TERMINATION ARGUMENT: busy waiting loop
try {
Thread.sleep(Options.TimedDynamicCounters.getValue(options));
} catch (InterruptedException e) {
}
long time = System.nanoTime();
dump(options, scope.out, (time - lastTime) / 1000000000d, jvmciRuntime.collectCounters(), 10);
lastTime = time;
}
}
}View on GitHub (pinned to a66e9ccd1d)
Solutions
- Drop -Dgraal.TimedDynamicCounters when running libgraal.
- Switch to jargraal mode if you need periodic dumps (run the compiler as Java, e.g. -Dgraal.JVMCILibGraal=false where supported).
- Use one-shot counter dumps (-Dgraal.BenchmarkDynamicCounters triples or dump-on-exit) instead of timed dumps under libgraal.
Example fix
# before -XX:+UseJVMCICompiler -Dgraal.TimedDynamicCounters=1000 # GraalError: Use of TimedDynamicCounters is only supported in jargraal # after -XX:+UseJVMCICompiler # timed counters removed under libgraal
Defensive patterns
Strategy: validation
Validate before calling
// Do not set TimedDynamicCounters when running libgraal
boolean libgraal = Boolean.parseBoolean(System.getProperty("graal.JVMCILibGraal", "true"));
long timed = Long.getLong("graal.TimedDynamicCounters", 0);
if (libgraal && timed > 0) {
throw new IllegalStateException("graal.TimedDynamicCounters requires jargraal mode; unset it or disable libgraal");
} Prevention
- Split benchmark flag sets into 'libgraal-safe' and 'jargraal-only' groups.
- Assert runtime mode before applying jargraal-only options.
When it happens
Trigger: Running with -XX:+UseJVMCICompiler in the default libgraal mode (no -Dgraal.JVMCILibGraal=false or equivalent) together with -Dgraal.TimedDynamicCounters=<ms>>0; LibGraalSupport.inLibGraalRuntime() returns true and the check fires.
Common situations: Reusing a benchmarking flag set that was tuned for jargraal on a JDK that now defaults to libgraal; nightly perf scripts that time-slice counter dumps.
Related errors
- too many counters, reduce number of counters or increase -XX
- invalid arguments to BenchmarkDynamicCounters: (err|out),sta
- invalid arguments to BenchmarkDynamicCounters: err|out
- LogFile substitution %s cannot be combined with any other ch
- Profile file for path %s exists already
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/9ff2aaa056929c77.
Report an issue: GitHub.