{"record":{"id":"f4ec29dca96dc29f","repo":"brettwooldridge/HikariCP","slug":"invalid-transaction-isolation-value-transaction","errorCode":null,"errorMessage":"Invalid transaction isolation value: ${transactionIsolationName}","messagePattern":"Invalid transaction isolation value: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/zaxxer/hikari/util/UtilityElf.java","lineNumber":220,"sourceCode":"    */\n   public static int getTransactionIsolation(final String transactionIsolationName)\n   {\n      if (transactionIsolationName != null) {\n         try {\n            // use the english locale to avoid the infamous turkish locale bug\n            final var upperCaseIsolationLevelName = transactionIsolationName.toUpperCase(Locale.ENGLISH);\n            return IsolationLevel.valueOf(upperCaseIsolationLevelName).getLevelId();\n         } catch (IllegalArgumentException e) {\n            // legacy support for passing an integer version of the isolation level\n            try {\n               final var level = Integer.parseInt(transactionIsolationName);\n               for (var iso : IsolationLevel.values()) {\n                  if (iso.getLevelId() == level) {\n                     return iso.getLevelId();\n                  }\n               }\n\n               throw new IllegalArgumentException(\"Invalid transaction isolation value: \" + transactionIsolationName);\n            }\n            catch (NumberFormatException nfe) {\n               throw new IllegalArgumentException(\"Invalid transaction isolation value: \" + transactionIsolationName, nfe);\n            }\n         }\n      }\n\n      return -1;\n   }\n\n   /**\n    * Custom RejectedExecutionHandler that does nothing when a task is rejected.\n    *\n    * @see java.util.concurrent.RejectedExecutionHandler\n    * @see java.util.concurrent.ThreadPoolExecutor\n    * @hidden\n    */\n   public static class CustomDiscardPolicy implements RejectedExecutionHandler","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/brettwooldridge/HikariCP/blob/a4d93f4f85517f90e632b795486d7102e933d7ff/src/main/java/com/zaxxer/hikari/util/UtilityElf.java#L202-L238","documentation":"UtilityElf.getTransactionIsolation(name) resolves the transactionIsolation HikariCP property. It first tries IsolationLevel.valueOf(name.toUpperCase(Locale.ENGLISH)); if that fails it falls back to legacy integer parsing. This exception is thrown when the value parsed as an integer successfully but that integer does not equal any known isolation level id (e.g. 6, 0, or -1 is not matched unless an enum has that id). In other words: the config value was numeric but not one of the recognized java.sql.Connection level constants (2=READ_COMMITTED, 4=REPEATABLE_READ, 8=SERIALIZABLE, 1=READ_UNCOMMITTED).","triggerScenarios":"Setting transactionIsolation=6 or any integer other than 1/2/4/8 in HikariConfig; passing a numeric string like \"8 \" (leading/trailing whitespace usually survives parseInt=ok but 8 matches; values like \"0\" or \"-1\" fail the loop); calling HikariConfig.setTransactionIsolation(\"5\") programmatically; tools that generate the config with a computed isolation integer that is not a standard level.","commonSituations":"Copy-pasting a database-vendor isolation constant (e.g. a driver-specific level like SQL Server's SNAPSHOT or Oracle's 8 vs vendor codes) into transactionIsolation; converting a GUI/container isolation dropdown that emits non-standard numbers; mixing up transactionIsolation (expects name or standard int) with a custom connection-init-sql; Spring's spring.datasource.hikari.transaction-isolation set to a vendor-specific numeric level.","solutions":["Use the standard level NAME instead of a number: transactionIsolation=READ_COMMITTED (also READ_UNCOMMITTED, REPEATABLE_READ, SERIALIZABLE) — names are matched case-insensitively via toUpperCase(Locale.ENGLISH).","If you must use an integer, use one of the java.sql.Connection constants: 1 (TRANSACTION_READ_UNCOMMITTED), 2 (TRANSACTION_READ_COMMITTED), 4 (TRANSACTION_REPEATABLE_READ), 8 (TRANSACTION_SERIALIZABLE).","For vendor-specific isolation levels not in that set (e.g. SQL Server SNAPSHOT), remove transactionIsolation and apply it via connectionInitSql (e.g. 'SET TRANSACTION ISOLATION LEVEL SNAPSHOT') or a ConnectionCustomizer.","Check for typos/whitespace in the property value — 'read-committed' with a hyphen also fails valueOf and then fails the int path with error 42."],"exampleFix":"// before\nconfig.setTransactionIsolation(\"6\"); // not a standard level -> IllegalArgumentException\n\n// after\nconfig.setTransactionIsolation(\"SERIALIZABLE\"); // or \"READ_COMMITTED\", \"REPEATABLE_READ\", ...","handlingStrategy":"validation","validationCode":"// Validate before calling config.setTransactionIsolation(...) / before pool init\nprivate static final Set<String> VALID_NAMES = Set.of(\n    \"READ_UNCOMMITTED\", \"READ_COMMITTED\", \"REPEATABLE_READ\", \"SERIALIZABLE\");\nprivate static final Set<Integer> VALID_IDS = Set.of(1, 2, 4, 8); // java.sql.Connection constants\n\nstatic String normalizeIsolation(String raw) {\n    if (raw == null) return null;\n    String v = raw.trim().toUpperCase(Locale.ENGLISH);\n    if (VALID_NAMES.contains(v)) return v;\n    try {\n        int n = Integer.parseInt(v);\n        if (VALID_IDS.contains(n)) return v;\n    } catch (NumberFormatException ignored) { }\n    throw new IllegalArgumentException(\n        \"transactionIsolation must be one of \" + VALID_NAMES + \" or one of \" + VALID_IDS + \", got: \" + raw);\n}","typeGuard":null,"tryCatchPattern":"// If isolation comes from external config at runtime\ntry {\n    config.setTransactionIsolation(rawValue);\n} catch (IllegalArgumentException e) {\n    throw new ConfigurationError(\"Invalid transactionIsolation '\" + rawValue\n        + \"': use READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE, or 1/2/4/8\", e);\n}","preventionTips":["Prefer the level NAME over the integer in config files — it is self-documenting and survives constant renumbering confusion.","If using integers, reference java.sql.Connection.TRANSACTION_* constants instead of hardcoding numbers.","For vendor-specific levels (e.g. SQL Server SNAPSHOT), use connectionInitSql instead of transactionIsolation.","Validate isolation values in your config layer at startup (see validationCode) rather than letting the pool throw during initialization."],"tags":["hikaricp","configuration","transaction-isolation","jdbc","validation"],"backgroundTag":null,"analyzedSha":"a4d93f4f85517f90e632b795486d7102e933d7ff","analyzedAt":"2026-08-14T12:11:37.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}