{"record":{"id":"a2144589c5ffa11a","repo":"quarkusio/quarkus","slug":"duration-cannot-be-negative","errorCode":null,"errorMessage":"Duration cannot be negative.","messagePattern":"Duration cannot be negative\\.","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/reactive-datasource/runtime/src/main/java/io/quarkus/reactive/datasource/runtime/UnitisedTime.java","lineNumber":26,"sourceCode":"    public final int value;\n    public final TimeUnit unit;\n\n    public UnitisedTime(int value, TimeUnit unit) {\n        this.value = value;\n        this.unit = unit;\n    }\n\n    /**\n     * Convert a {@link Duration} to a {@link UnitisedTime} with the smallest possible\n     * {@link TimeUnit} starting from {@link TimeUnit#MILLISECONDS}.\n     *\n     * @param duration Duration to convert\n     *\n     * @return UnitisedTime\n     */\n    public static UnitisedTime unitised(Duration duration) {\n        if (duration.isNegative()) {\n            throw new IllegalArgumentException(\"Duration cannot be negative.\");\n        }\n\n        long millis = duration.toMillis();\n        if (millis < Integer.MAX_VALUE) {\n            return new UnitisedTime((int) millis, TimeUnit.MILLISECONDS);\n        }\n\n        long seconds = duration.getSeconds();\n        if (seconds < Integer.MAX_VALUE) {\n            return new UnitisedTime((int) seconds, TimeUnit.SECONDS);\n        }\n\n        long minutes = duration.toMinutes();\n        if (minutes < Integer.MAX_VALUE) {\n            return new UnitisedTime((int) minutes, TimeUnit.MINUTES);\n        }\n\n        long hours = duration.toHours();","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/reactive-datasource/runtime/src/main/java/io/quarkus/reactive/datasource/runtime/UnitisedTime.java#L8-L44","documentation":"UnitisedTime.unitised() converts a java.time.Duration into a (value, TimeUnit) pair for Vert.x pool options. Negative durations are invalid for pool timeouts, so it throws IllegalArgumentException early instead of passing a nonsensical negative timeout to the client.","triggerScenarios":"Passing a negative Duration (e.g. Duration.ofSeconds(-1)) to unitised(), which happens when reactive pool timeout configs such as connect-timeout or idle-timeout are set to a negative value.","commonSituations":"Misreading a config option as 'disabled by negative value'; unit mistakes like -1 in quarkus.datasource.\"x\".reactive.connect-timeout; building runtime config programmatically with a sentinel -1.","solutions":["Set the offending quarkus.datasource.\"<name>\".reactive.<timeout> property to zero or a positive duration","Use Duration.ZERO or remove the property to rely on defaults — never a negative value","In programmatic use, validate Duration arguments before calling UnitisedTime.unitised()"],"exampleFix":"// before\nquarkus.datasource.db.reactive.connect-timeout=-1s\n// after\nquarkus.datasource.db.reactive.connect-timeout=5s","handlingStrategy":"validation","validationCode":"if (duration != null && duration.isNegative()) {\n    throw new IllegalArgumentException(\"Timeout must be >= 0: \" + duration);\n}\nUnitisedTime t = UnitisedTime.unitised(duration);","typeGuard":null,"tryCatchPattern":"try {\n    UnitisedTime t = UnitisedTime.unitised(duration);\n} catch (IllegalArgumentException e) {\n    duration = Duration.ZERO; // or a sensible default\n}","preventionTips":["Never use negative values to 'disable' reactive timeouts","Use Duration.ZERO or omit the property for defaults","Validate Duration configs in @ConfigMapping validators"],"tags":["quarkus","reactive-datasource","duration","validation"],"backgroundTag":"negative-duration","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}