{"record":{"id":"2345b05eaa86db0a","repo":"eclipse-vertx/vert.x","slug":"timeout-must-be-0-2345b0","errorCode":null,"errorMessage":"Timeout  must be >= 0","messagePattern":"Timeout  must be >= 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/net/impl/ShutdownEvent.java","lineNumber":29,"sourceCode":"package io.vertx.core.net.impl;\n\nimport java.time.Duration;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * Signals that a resource will be closed within a certain amount of time.\n */\npublic class ShutdownEvent {\n\n  private final Duration timeout;\n\n  public ShutdownEvent(long timeout, TimeUnit timeUnit) {\n    this(Duration.ofMillis(timeUnit.toMillis(timeout)));\n  }\n\n  public ShutdownEvent(Duration timeout) {\n    if (timeout.isNegative()) {\n      throw new IllegalArgumentException(\"Timeout \" + timeout + \" must be >= 0\");\n    }\n    this.timeout = timeout;\n  }\n\n  public Duration timeout() {\n    return timeout;\n  }\n}\n","sourceCodeStart":11,"sourceCodeEnd":38,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/net/impl/ShutdownEvent.java#L11-L38","documentation":"ShutdownEvent validates its timeout: a negative Duration is rejected with IllegalArgumentException ('Timeout X must be >= 0'). A shutdown timeout defines how long to wait for graceful connection close, so negative values are meaningless. Zero is allowed (immediate shutdown).","triggerScenarios":"Constructing new ShutdownEvent(-1, TimeUnit.SECONDS) or new ShutdownEvent(Duration.ofSeconds(-1)), or passing a negative computed duration from config.","commonSituations":"Config value parsed as negative (e.g. '-1' meaning 'disabled' in the user's config convention), or arithmetic on durations that underflows (a - now).","solutions":["Clamp the timeout before constructing: Duration.ofMillis(Math.max(0, millis))","Treat negative configured values as 'no timeout' and use a large/default duration instead","Fix config files that use -1 as a sentinel for 'disabled'"],"exampleFix":"// before\nlong timeout = config.getLong(\"shutdownTimeout\", -1L);\nvertx.close(new ShutdownEvent(timeout, TimeUnit.MILLISECONDS));\n// after\nlong timeout = config.getLong(\"shutdownTimeout\", 0L);\nvertx.close(new ShutdownEvent(Math.max(0, timeout), TimeUnit.MILLISECONDS));","handlingStrategy":"validation","validationCode":"if (timeout < 0) throw new IllegalArgumentException(\"shutdown timeout must be >= 0, got \" + timeout);\nnew ShutdownEvent(timeout, TimeUnit.MILLISECONDS);","typeGuard":null,"tryCatchPattern":"try {\n  new ShutdownEvent(cfgTimeout, TimeUnit.MILLISECONDS);\n} catch (IllegalArgumentException e) {\n  // log and clamp to 0 or a default\n}","preventionTips":["Clamp negative config values with Math.max(0, value)","Don't use -1 as a sentinel for 'disabled' in duration configs","Compute remaining-time durations with .isNegative() checks"],"tags":["timeout","validation","shutdown"],"backgroundTag":"argument-out-of-range","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}