{"record":{"id":"5f3f2833fdfd1cb0","repo":"tursodatabase/turso","slug":"query-timeout-must-be-greater-than-0","errorCode":null,"errorMessage":"Query timeout must be greater than 0","messagePattern":"Query timeout must be greater than 0","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"bindings/java/src/main/java/tech/turso/jdbc4/JDBC4Statement.java","lineNumber":164,"sourceCode":"  public void setMaxRows(int max) throws SQLException {\n    // TODO\n  }\n\n  @Override\n  public void setEscapeProcessing(boolean enable) throws SQLException {\n    // TODO\n  }\n\n  @Override\n  public int getQueryTimeout() throws SQLException {\n    // TODO\n    return 0;\n  }\n\n  @Override\n  public void setQueryTimeout(int seconds) throws SQLException {\n    if (seconds < 0) {\n      throw new SQLException(\"Query timeout must be greater than 0\");\n    }\n    this.queryTimeoutSeconds = seconds;\n  }\n\n  @Override\n  public void cancel() throws SQLException {\n    // TODO\n  }\n\n  @Override\n  @SkipNullableCheck\n  public SQLWarning getWarnings() throws SQLException {\n    // TODO\n    return null;\n  }\n\n  @Override\n  public void clearWarnings() throws SQLException {","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/java/src/main/java/tech/turso/jdbc4/JDBC4Statement.java#L146-L182","documentation":"JDBC4Statement.setQueryTimeout(int) rejects negative values with SQLException(\"Query timeout must be greater than 0\"). The message is misleading: the guard is `seconds < 0`, so 0 (which in JDBC means 'no timeout') is accepted — only negatives throw. Note also that the stored value is not enforced yet; getQueryTimeout() is a TODO stub returning 0.","triggerScenarios":"Calling stmt.setQueryTimeout(-1) or any negative value. Frequently the negative comes from a convention where -1 means 'unlimited' or 'use default' (MyBatis/Spring-style timeout properties) and is passed through unclamped; also from parsing a user- or config-supplied timeout string without validation.","commonSituations":"Properties files with timeout=-1; frameworks that mirror java.sql defaults of -1 and call setQueryTimeout unconditionally; migration from drivers that accept -1 silently.","solutions":["Clamp the configured value to >= 0 before calling (map -1/'unlimited' to 0)","Fix the source configuration to a valid non-negative timeout","Validate externally supplied timeout input early and fail with your own error message"],"exampleFix":"// before\nstmt.setQueryTimeout(configuredTimeout); // -1 -> SQLException\n\n// after\nint timeout = Math.max(0, configuredTimeout);\nstmt.setQueryTimeout(timeout);","handlingStrategy":"validation","validationCode":"int safeTimeout = timeoutSeconds < 0 ? 0 : timeoutSeconds; // -1/'unlimited' -> 0\nstmt.setQueryTimeout(safeTimeout);","typeGuard":null,"tryCatchPattern":"try {\n  stmt.setQueryTimeout(timeoutSeconds);\n} catch (SQLException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Query timeout\")) {\n    stmt.setQueryTimeout(0); // retry with 'no timeout'\n  } else {\n    throw e;\n  }\n}","preventionTips":["Clamp every externally sourced timeout to >= 0 before calling setQueryTimeout","Use 0 for 'disabled'; do not use -1 conventions with this driver","Note the driver does not enforce the timeout yet — do not rely on it for cancellation"],"tags":["java","jdbc","turso","statement","timeout","validation"],"backgroundTag":"invalid-timeout-value","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}