quarkusio/quarkus · error · IllegalStateException

JMX is not available in native images.

Error message

JMX is not available in native images.

What it means

In native images Quarkus substitutes Caffeine JCache's CacheProxy.enableManagement() because JMX is unavailable in native mode. The substitute throws an IllegalStateException if management (JMX exposure of the cache) is requested with enabled=true, instead of silently enabling it.

Source

Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/graal/Substitute_CacheProxy.java:17

package io.quarkus.hibernate.orm.runtime.graal;

import com.github.benmanes.caffeine.jcache.CacheProxy;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;

/**
 * Removes some caffeine-jcache features related to JMX,
 * because we don't want to put in the work to make that work in native mode.
 */
// TODO should this be in quarkus-caffeine, with caffeine-jcache as a "provided" dependency?
@TargetClass(CacheProxy.class)
final class Substitute_CacheProxy {
    @Substitute
    void enableManagement(boolean enabled) {
        if (enabled) {
            throw new IllegalStateException("JMX is not available in native images.");
        }
    }

    @Substitute
    void enableStatistics(boolean enabled) {
        if (enabled) {
            throw new IllegalStateException("JMX is not available in native images.");
        }
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Disable cache JMX management when running in native mode (setManagementEnabled(false) or remove the JMX config property).
  2. Gate the JMX-enabling code behind a runtime check for native image, enabling it only on the JVM.
  3. Use alternative monitoring (e.g. Micrometer metrics exposed by Quarkus) instead of JMX in native mode.
  4. Only call enableManagement when users explicitly opt into JMX via configuration that defaults to off.

Example fix

// before
cache.enableManagement(true);

// after
if (!ImageInfo.inImageCode()) {
  cache.enableManagement(true);
}
Defensive patterns

Strategy: fallback

Validate before calling

// Only enable JMX management when not running as a native image
if (!io.quarkus.runtime.ImageInfo.inImageCode()) {
    cache.setManagementEnabled(true);
}

Try / catch

try {
    cache.enableManagement(true);
} catch (IllegalStateException e) {
    if ("JMX is not available in native images.".equals(e.getMessage())) {
        log.info("Skipping cache JMX management in native mode; using Micrometer instead");
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Running a native-image build and enabling JMX management for a Caffeine JCache — e.g. via cache configuration setManagementEnabled(true) or JMX-related cache properties — which invokes the substituted enableManagement(true).

Common situations: Porting a JVM-mode app to native where caches had JMX statistics/management enabled in configuration; enabling JMX monitoring code paths unconditionally in shared cache setup code.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/ad557ff03316ed3c. Report an issue: GitHub.