tursodatabase/turso · error · SQLException

Query timeout must be greater than 0

Error message

Query timeout must be greater than 0

What it means

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.

Solutions

  1. Clamp the configured value to >= 0 before calling (map -1/'unlimited' to 0)
  2. Fix the source configuration to a valid non-negative timeout
  3. Validate externally supplied timeout input early and fail with your own error message

Example fix

// before
stmt.setQueryTimeout(configuredTimeout); // -1 -> SQLException

// after
int timeout = Math.max(0, configuredTimeout);
stmt.setQueryTimeout(timeout);
Defensive patterns

Strategy: validation

Validate before calling

int safeTimeout = timeoutSeconds < 0 ? 0 : timeoutSeconds; // -1/'unlimited' -> 0
stmt.setQueryTimeout(safeTimeout);

Try / catch

try {
  stmt.setQueryTimeout(timeoutSeconds);
} catch (SQLException e) {
  if (e.getMessage() != null && e.getMessage().contains("Query timeout")) {
    stmt.setQueryTimeout(0); // retry with 'no timeout'
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: Properties files with timeout=-1; frameworks that mirror java.sql defaults of -1 and call setQueryTimeout unconditionally; migration from drivers that accept -1 silently.

Understand the failure class

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/5f3f2833fdfd1cb0. Report an issue: GitHub.

Appendix: source

Thrown at bindings/java/src/main/java/tech/turso/jdbc4/JDBC4Statement.java:164

  public void setMaxRows(int max) throws SQLException {
    // TODO
  }

  @Override
  public void setEscapeProcessing(boolean enable) throws SQLException {
    // TODO
  }

  @Override
  public int getQueryTimeout() throws SQLException {
    // TODO
    return 0;
  }

  @Override
  public void setQueryTimeout(int seconds) throws SQLException {
    if (seconds < 0) {
      throw new SQLException("Query timeout must be greater than 0");
    }
    this.queryTimeoutSeconds = seconds;
  }

  @Override
  public void cancel() throws SQLException {
    // TODO
  }

  @Override
  @SkipNullableCheck
  public SQLWarning getWarnings() throws SQLException {
    // TODO
    return null;
  }

  @Override
  public void clearWarnings() throws SQLException {

View on GitHub (pinned to 244cde92a7)