brettwooldridge/HikariCP · error · RuntimeException

Failed to instantiate class ${exceptionOverrideClassName}

Error message

Failed to instantiate class ${exceptionOverrideClassName}

What it means

setExceptionOverrideClassName(String) reflectively loads and instantiates the named class as a SQLExceptionOverride; any failure (missing class, wrong type, missing no-arg constructor, constructor throw) is wrapped in a RuntimeException 'Failed to instantiate class <name>'. The override customizes which SQLExceptions HikariCP treats as pool-evicting, so a broken override must fail fast rather than fall back to defaults silently.

Source

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

      return this.exceptionOverrideClassName;
   }

   /**
    * Set the user supplied SQLExceptionOverride class name.
    *
    * @param exceptionOverrideClassName the user supplied SQLExceptionOverride class name
    * @see SQLExceptionOverride
    */
   public void setExceptionOverrideClassName(String exceptionOverrideClassName)
   {
      checkIfSealed();

      try {
         this.exceptionOverride = createInstance(exceptionOverrideClassName, SQLExceptionOverride.class);
         this.exceptionOverrideClassName = exceptionOverrideClassName;
      }
      catch (Exception e) {
         throw new RuntimeException("Failed to instantiate class " + exceptionOverrideClassName, e);
      }
   }

   /**
    * Get the SQLExceptionOverride instance created by {@link #setExceptionOverrideClassName(String)} or specified by
    * {@link #setExceptionOverride(SQLExceptionOverride)}.
    *
    * @return the SQLExceptionOverride instance, or null
    * @see SQLExceptionOverride
    */
   public SQLExceptionOverride getExceptionOverride()
   {
      return this.exceptionOverride;
   }

   /**
    * Set the user supplied SQLExceptionOverride instance.
    *

View on GitHub (pinned to a4d93f4f85)

Solutions

  1. Check the wrapped cause exception for the true failure (ClassNotFound vs InstantiationException vs constructor error)
  2. Fix the FQCN in config to match the actual class, or ship the jar containing it
  3. Give the class a public no-arg constructor and keep construction side-effect free
  4. Prefer the type-safe alternative: setExceptionOverride(new MyOverride()) since you are compiling against the interface anyway

Example fix

// before
config.setExceptionOverrideClassName("com.acme.MySqlExceptionOverride"); // RuntimeException

// after
config.setExceptionOverride(new com.acme.MySqlExceptionOverride());
Defensive patterns

Strategy: try-catch

Validate before calling

try {
   Class.forName(overrideClassName).asSubclass(com.zaxxer.hikari.SQLExceptionOverride.class)
       .getConstructor().newInstance();
} catch (ReflectiveOperationException e) {
   throw new IllegalStateException("SQLExceptionOverride unusable: " + overrideClassName, e);
}

Try / catch

try {
   config.setExceptionOverrideClassName(cls);
} catch (RuntimeException e) {
   log.error("Cannot install SQLExceptionOverride {} ({}); starting with default eviction behavior", cls, e.getCause(), e);
   // only continue without the override if that is acceptable
}

Prevention

When it happens

Trigger: Class name typo; class not shipped in the deployment artifact; class does not implement SQLExceptionOverride; only a parameterized constructor is defined; constructor performs work that fails in the target environment.

Common situations: Teams shipping a shared 'hikari-overrides' library that a service forgets as a dependency; renaming the override class during a refactor while config still references the old FQCN; constructor reading database/vault state that is unavailable during bean construction.

Related errors


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