#2378·HikariCP

Potential connection starvation due to DiscardPolicy usage in addConnectionExecutor

Author: QiuYucheng2003Created Jan 8, 2026Updated Jan 8, 2026

I have analyzed the source code of HikariPool.java and identified a potential issue related to the thread pool configuration for addConnectionExecutor.

The addConnectionExecutor is responsible for creating new physical connections and adding them to the pool. Currently, it is configured with a CustomDiscardPolicy (which behaves similarly to DiscardPolicy).

Location File: src/main/java/com/zaxxer/hikari/pool/HikariPool.java Line: 118 (in the constructor) Code: this.addConnectionExecutor = createThreadPoolExecutor(maxPoolSize, poolName + ":connection-adder", threadFactory, new CustomDiscardPolicy());

Analysis In a high-concurrency scenario, if the addConnectionExecutor queue becomes full, the CustomDiscardPolicy will silently drop new PoolEntryCreator tasks.

Although addBagItem (line 412) attempts to check the queue size (if (waiting > addConnectionExecutor.getQueue().size())), a race condition or a sudden spike in requests could still result in the task submission being rejected by the policy.

If the task is discarded:

  1. No new connection is created.
  2. Threads waiting in connectionBag.borrow() will continue to wait until they timeout (SQLTransientConnectionException).
  3. The pool fails to expand to maximumPoolSize even though the database might be healthy.

This fits the DenyPolicySettingError (DPSE) pattern, where using a discard policy for critical resource production tasks leads to silent failures and resource starvation.

Suggested Fix Consider changing the rejection policy to CallerRunsPolicy or ensuring that the CustomDiscardPolicy provides a fallback mechanism (e.g., logging a warning or retrying) rather than silently ignoring the request.

Using CallerRunsPolicy would ensure that if the executor is busy, the calling thread (which is likely waiting for a connection anyway) assists in creating the connection, thus preventing task loss. // Suggested change: this.addConnectionExecutor = createThreadPoolExecutor(maxPoolSize, poolName + ":connection-adder", threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());

Environment HikariCP version: (Master) JDK version: 1.8

Source: brettwooldridge/HikariCP