SonarSource/sonarqube · error · IllegalArgumentException

Read timeout must be positive. Got

Error message

Read timeout must be positive. Got 

What it means

OkHttpClientBuilder.setReadTimeoutMs(long) throws IllegalArgumentException when given a negative value. Zero means no read timeout; the OkHttp default otherwise applies. Like the connect-timeout setter, it validates eagerly so a misconfigured builder fails immediately rather than at request time.

Solutions

  1. Pass 0 to disable the read timeout (not -1)
  2. Clamp with Math.max(0, readTimeoutMs) before calling
  3. Fix the configuration source supplying the negative number

Example fix

// before
builder.setReadTimeoutMs(-1); // intended 'no timeout'
// after
builder.setReadTimeoutMs(0); // 0 = no timeout
Defensive patterns

Strategy: validation

Validate before calling

if (readTimeoutMs < 0) throw new IllegalArgumentException("readTimeoutMs must be >= 0, got " + readTimeoutMs);
builder.setReadTimeoutMs(Math.max(0, readTimeoutMs));

Try / catch

try {
  builder.setReadTimeoutMs(cfg.readTimeoutMs());
} catch (IllegalArgumentException e) {
  log.warn("Bad read timeout, using default", e);
}

Prevention

When it happens

Trigger: Calling setReadTimeoutMs with a negative long, e.g. from a parsed configuration value or computed duration that went negative; called via provide() or HttpConnector setup.

Common situations: Negative values in sonar.properties or client config; duration arithmetic underflow; users setting '-1' expecting 'infinite' instead of the API's 0-for-none convention.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/796c55a2da398b33. Report an issue: GitHub.

Appendix: source

Thrown at sonar-ws/src/main/java/org/sonarqube/ws/client/OkHttpClientBuilder.java:172

    this.connectTimeoutMs = l;
    return this;
  }

  /**
   * Set credentials that will be passed on every request
   */
  public OkHttpClientBuilder setCredentials(String credentials) {
    this.credentials = credentials;
    return this;
  }

  /**
   * Sets the default read timeout for new connections. A value of 0 means no timeout.
   * Default is defined by OkHttp (10 seconds in OkHttp 3.3).
   */
  public OkHttpClientBuilder setReadTimeoutMs(long l) {
    if (l < 0) {
      throw new IllegalArgumentException("Read timeout must be positive. Got " + l);
    }
    this.readTimeoutMs = l;
    return this;
  }

  /**
   * Sets the default response timeout for new connections. A value of 0 means no timeout.
   * Default is to have no timeout.
   */
  public OkHttpClientBuilder setResponseTimeoutMs(long l) {
    if (l < 0) {
      throw new IllegalArgumentException("Response timeout must be positive. Got " + l);
    }
    this.responseTimeoutMs = l;
    return this;
  }

  /**

View on GitHub (pinned to 184c821202)