brettwooldridge/HikariCP · error · IllegalArgumentException
Class must be instance of com.codahale.metrics.MetricRegistr
Error message
Class must be instance of com.codahale.metrics.MetricRegistry, io.dropwizard.metrics5.MetricRegistry, or io.micrometer.core.instrument.MeterRegistry
What it means
When setMetricRegistry(Object) receives a non-null object, HikariCP first resolves it (unwrapping/JNDI lookup via getObjectOrPerformJndiLookup) and then verifies it is a com.codahale.metrics.MetricRegistry, io.dropwizard.metrics5.MetricRegistry, or io.micrometer.core.instrument.MeterRegistry. Anything else throws IllegalArgumentException — HikariCP has reflective (not compile-time) support for these libraries, so it must type-check at runtime.
Source
Thrown at src/main/java/com/zaxxer/hikari/HikariConfig.java:684
/**
* Set a MetricRegistry instance to use for registration of metrics used by HikariCP.
*
* @param metricRegistry the MetricRegistry instance to use
*/
public void setMetricRegistry(Object metricRegistry)
{
if (metricsTrackerFactory != null) {
throw new IllegalStateException("cannot use setMetricRegistry() and setMetricsTrackerFactory() together");
}
if (metricRegistry != null) {
metricRegistry = getObjectOrPerformJndiLookup(metricRegistry);
if (!safeIsAssignableFrom(metricRegistry, "com.codahale.metrics.MetricRegistry")
&& !(safeIsAssignableFrom(metricRegistry, "io.dropwizard.metrics5.MetricRegistry"))
&& !(safeIsAssignableFrom(metricRegistry, "io.micrometer.core.instrument.MeterRegistry"))) {
throw new IllegalArgumentException("Class must be instance of com.codahale.metrics.MetricRegistry, " +
"io.dropwizard.metrics5.MetricRegistry, or io.micrometer.core.instrument.MeterRegistry");
}
}
this.metricRegistry = metricRegistry;
}
/**
* Get the HealthCheckRegistry that will be used for registration of health checks by HikariCP. Currently only
* Codahale/DropWizard is supported for health checks.
*
* @return the HealthCheckRegistry instance that will be used
*/
public Object getHealthCheckRegistry()
{
return healthCheckRegistry;
}
View on GitHub (pinned to a4d93f4f85)
Solutions
- Pass a Micrometer MeterRegistry (recommended, wraps everything) — e.g. Metrics.globalRegistry or an injected MeterRegistry
- If using Dropwizard, pass the actual com.codahale.metrics.MetricRegistry or io.dropwizard.metrics5.MetricRegistry instance
- For Prometheus exposure, add micrometer-registry-prometheus and pass its PrometheusMeterRegistry — never the raw CollectorRegistry
- If the value comes from JNDI/properties, verify what the name actually resolves to at runtime before wiring it
Example fix
// before config.setMetricRegistry(prometheusCollectorRegistry); // IllegalArgumentException // after // with micrometer-registry-prometheus on the classpath PrometheusMeterRegistry promRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); config.setMetricRegistry(promRegistry);
Defensive patterns
Strategy: type-guard
Type guard
static boolean isSupportedMetricRegistry(Object o) {
return o instanceof io.micrometer.core.instrument.MeterRegistry
|| o instanceof com.codahale.metrics.MetricRegistry
|| o instanceof io.dropwizard.metrics5.MetricRegistry;
}
// use: if (isSupportedMetricRegistry(candidate)) config.setMetricRegistry(candidate); Try / catch
catch (IllegalArgumentException e) {
log.error("Unsupported metric registry type: {} — pass a Micrometer MeterRegistry", candidate.getClass(), e);
} Prevention
- Prefer Micrometer MeterRegistry as the universal adapter
- Do not pass raw Prometheus CollectorRegistry — wrap it with micrometer-registry-prometheus
- When the value comes from JNDI/properties, resolve and type-check it before wiring
When it happens
Trigger: Passing a generic Object from configuration/properties that resolves to the wrong type, e.g. a String JNDI name that resolves to a HealthCheckRegistry, a Prometheus CollectorRegistry, a Micrometer Clock, or a plain map; passing a class instead of an instance; a JNDI lookup returning an unexpected object type.
Common situations: Using Prometheus directly (CollectorRegistry is NOT a Micrometer MeterRegistry — you need micrometer-registry-prometheus to wrap it); binding the wrong JNDI name in an app server; version drift where the registry class moved between packages (metrics-core 2.x codahale vs 3/4/5 dropwizard); scripted/XML config where the property is a string resolved at runtime.
Related errors
- cannot use setMetricsTrackerFactory() and setMetricRegistry(
- cannot use setMetricRegistry() and setMetricsTrackerFactory(
- Class must be an instance of com.codahale.metrics.health.Hea
- MetricRegistry can only be set one time
- MetricsTrackerFactory can only be set one time
AI-assisted analysis of brettwooldridge/HikariCP@a4d93f4f85 (2026-08-14).
Data as JSON: /api/errors/9fc650fcfea64b46.
Report an issue: GitHub.