brettwooldridge/HikariCP · error · IllegalStateException

cannot use setMetricRegistry() and setMetricsTrackerFactory(

Error message

cannot use setMetricRegistry() and setMetricsTrackerFactory() together

What it means

Mirror of the setMetricsTrackerFactory() guard: setMetricRegistry(Object) throws IllegalStateException if a MetricsTrackerFactory has already been configured. HikariCP only allows one metrics backend, and a previously set factory means the registry would be ignored or double-report. Ordering matters — whichever setter runs second loses.

Source

Thrown at src/main/java/com/zaxxer/hikari/HikariConfig.java:675

   /**
    * Get the MetricRegistry instance to use for registration of metrics used by HikariCP.  Default is {@code null}.
    *
    * @return the MetricRegistry instance that will be used
    */
   public Object getMetricRegistry()
   {
      return metricRegistry;
   }

   /**
    * 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

View on GitHub (pinned to a4d93f4f85)

Solutions

  1. Remove one of the two: either drop the custom MetricsTrackerFactory or stop passing the registry
  2. In Spring Boot, exclude or rely on Hikari metric autoconfiguration rather than fighting it — set spring.datasource.hikari.* accordingly
  3. If both are needed in different environments, make the config assembly conditional (e.g. @ConditionalOnMissingBean) instead of unconditional
  4. Order and guard: check config.getMetricsTrackerFactory() == null before setting the registry

Example fix

// before
config.setMetricsTrackerFactory(customFactory);
config.setMetricRegistry(registry); // IllegalStateException

// after
if (config.getMetricsTrackerFactory() == null) {
   config.setMetricRegistry(registry);
}
Defensive patterns

Strategy: validation

Validate before calling

if (config.getMetricsTrackerFactory() == null) {
   config.setMetricRegistry(registry);
} // else: custom factory already installed

Prevention

When it happens

Trigger: config.setMetricsTrackerFactory(factory) followed by config.setMetricRegistry(registry); or properties-based configuration setting metricsTrackerFactory and then code (often framework autoconfiguration such as Spring Boot's HikariMetricsInitializer) setting the registry on the same HikariConfig instance afterwards.

Common situations: Spring Boot autoconfigures Micrometer metrics for HikariCP when micrometer is present, colliding with a hand-rolled MetricsTrackerFactory in application code; property files left over from a previous metrics approach; multi-module projects where each module touches the shared pool config.

Related errors


AI-assisted analysis of brettwooldridge/HikariCP@a4d93f4f85 (2026-08-14). Data as JSON: /api/errors/cf209b482aee9a7d. Report an issue: GitHub.