alibaba/spring-ai-alibaba · error · IllegalArgumentException

maxDelay must be greater than or equal to 0.

Error message

maxDelay must be greater than or equal to 0.

What it means

ModelRetryInterceptor's Builder.maxDelay() validates that the configured maximum retry delay is non-negative. A negative value would make retry backoff scheduling meaningless, so the builder rejects it eagerly with IllegalArgumentException. This is a fail-fast guard on configuration, not a runtime failure.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/modelretry/ModelRetryInterceptor.java:324

		/**
		 * Set the initial retry delay (milliseconds).
		 * @param initialDelay Initial delay time, in milliseconds
		 */
		public Builder initialDelay(long initialDelay) {
			if (initialDelay < 0) {
				throw new IllegalArgumentException("initialDelay must be greater than or equal to 0.");
			}
			this.initialDelay = initialDelay;
			return this;
		}

		/**
		 * Set the maximum retry delay (milliseconds).
		 * @param maxDelay Maximum delay time, in milliseconds
		 */
		public Builder maxDelay(long maxDelay) {
			if (maxDelay < 0) {
				throw new IllegalArgumentException("maxDelay must be greater than or equal to 0.");
			}
			this.maxDelay = maxDelay;
			return this;
		}

		/**
		 * Set the backoff factor (the multiplier for the delay time on each retry).
		 * @param backoffMultiplier The retreat factor must be >= 1.0
		 */
		public Builder backoffMultiplier(double backoffMultiplier) {
			if (backoffMultiplier < 1.0) {
				throw new IllegalArgumentException("The backoffMultiplier must be >= 1.0");
			}
			this.backoffMultiplier = backoffMultiplier;
			return this;
		}

		/**

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Pass a non-negative maxDelay (>= 0 ms)
  2. Clamp or Math.max(0, configuredValue) before calling maxDelay()
  3. Fix the config source so the delay property is not negative

Example fix

// before
new ModelRetryInterceptor.Builder().maxDelay(-500)
// after
new ModelRetryInterceptor.Builder().maxDelay(5000)
Defensive patterns

Strategy: validation

Validate before calling

if (configuredMaxDelay < 0) { throw new IllegalArgumentException("maxDelay must be >= 0, got " + configuredMaxDelay); }
interceptor = ModelRetryInterceptor.builder().maxDelay(Math.max(0, configuredMaxDelay)).build();

Type guard

boolean isValidMaxDelay(long d) { return d >= 0; }

Try / catch

try { builder.maxDelay(v); } catch (IllegalArgumentException e) { log.warn("Bad maxDelay, using default", e); builder.maxDelay(10_000); }

Prevention

When it happens

Trigger: Calling ModelRetryInterceptor.Builder.maxDelay() with a negative long, e.g. maxDelay(-1) or a negative value computed from config/properties.

Common situations: Config value read from YAML/properties parsed as negative; arithmetic like baseDelay - increment yielding negative; sign typo when hardcoding.

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 alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/b6eb0a288c75d9c8. Report an issue: GitHub.