brettwooldridge/HikariCP · error · IllegalStateException
MetricsTrackerFactory can only be set one time
Error message
MetricsTrackerFactory can only be set one time
What it means
setMetricsTrackerFactory() can only be assigned once before/while the pool starts; if a factory is already set and the pool exists, HikariDataSource throws IllegalStateException. The tracker factory is bound into the pool's metrics lifecycle at startup and cannot be swapped afterwards.
Solutions
- Set metricsTrackerFactory exactly once, before first connection acquisition
- Ensure metricRegistry and metricsTrackerFactory are not both being set by different components
- To replace the factory, tear down and rebuild the DataSource
- Configure it via HikariConfig before constructing HikariDataSource(config)
Example fix
// before ds.setMetricsTrackerFactory(factoryA); ds.setMetricsTrackerFactory(factoryB); // IllegalStateException // after HikariConfig cfg = new HikariConfig(); cfg.setMetricsTrackerFactory(factoryB); // single assignment pre-start HikariDataSource ds = new HikariDataSource(cfg);
Defensive patterns
Strategy: validation
Validate before calling
if (ds.getMetricsTrackerFactory() == null && ds.getMetricRegistry() == null) {
ds.setMetricsTrackerFactory(factory);
} Prevention
- Set metricsTrackerFactory exactly once pre-start
- Do not mix metricRegistry and metricsTrackerFactory on the same pool
- Centralize metrics wiring in one configuration class
When it happens
Trigger: Calling setMetricsTrackerFactory(...) twice on a live pool; specifying both metricRegistry and metricsTrackerFactory (framework may set one, your code the other); Prometheus/micrometer glue re-registering the factory on refresh.
Common situations: Custom MetricsTrackerFactory for Prometheus, repeated initialization during Spring context refresh, actuator endpoint that rebinds metrics.
Related errors
- MetricRegistry can only be set one time
- cannot use setMetricRegistry() and…
- cannot use setMetricsTrackerFactory() and…
- Class must be instance of…
- HealthCheckRegistry can only be set one time
AI-assisted analysis of brettwooldridge/HikariCP@a4d93f4f85 (2026-08-14).
Data as JSON: /api/errors/4b9680b9a1deea44.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/com/zaxxer/hikari/HikariDataSource.java:259
throw new IllegalStateException("MetricRegistry can only be set one time");
}
else {
p.setMetricRegistry(super.getMetricRegistry());
}
}
}
/** {@inheritDoc} */
@Override
public void setMetricsTrackerFactory(MetricsTrackerFactory metricsTrackerFactory)
{
var isAlreadySet = getMetricsTrackerFactory() != null;
super.setMetricsTrackerFactory(metricsTrackerFactory);
var p = pool;
if (p != null) {
if (isAlreadySet) {
throw new IllegalStateException("MetricsTrackerFactory can only be set one time");
}
else {
p.setMetricsTrackerFactory(super.getMetricsTrackerFactory());
}
}
}
/** {@inheritDoc} */
@Override
public void setHealthCheckRegistry(Object healthCheckRegistry)
{
var isAlreadySet = getHealthCheckRegistry() != null;
super.setHealthCheckRegistry(healthCheckRegistry);
var p = pool;
if (p != null) {
if (isAlreadySet) {
throw new IllegalStateException("HealthCheckRegistry can only be set one time");View on GitHub (pinned to a4d93f4f85)