redis/jedis · error · IllegalArgumentException
FAILOVER with force option requires both a timeout and…
Error message
FAILOVER with force option requires both a timeout and target HOST and IP.
What it means
CLUSTER FAILOVER with the FORCE option mandates, per the Redis protocol, both a TIMEOUT and a target (TO host:port). FailoverParams.addParams enforces this: if force is set but either to or timeout is missing, it throws IllegalArgumentException explaining the requirement before emitting the FORCE keyword.
Solutions
- Provide both to(host, port) and timeout(duration) whenever force() is used.
- If no target is intended, drop the force option and use a plain/takeover failover instead.
- Validate params construction order in helper code so force() is only reachable after to()/timeout() are set.
Example fix
// before
FailoverParams params = FailoverParams.FailoverParamsBuilder
.force().build(); // missing TO and TIMEOUT
// after
FailoverParams params = FailoverParams.FailoverParamsBuilder
.to("127.0.0.1", 6380)
.timeout(Duration.ofSeconds(60))
.force().build(); Defensive patterns
Strategy: validation
Validate before calling
if (useForce && (targetHost == null || targetPort <= 0 || timeoutMs <= 0)) {
throw new IllegalArgumentException("FAILOVER force requires TO host:port and TIMEOUT");
} Try / catch
try {
jedis.failover(params);
} catch (IllegalArgumentException e) {
// rebuild params with to() + timeout(), or retry without force
} Prevention
- Whenever force() is used, set to(host, port) and timeout(duration) in the same builder chain.
- Remember the client API enforces the TO/TIMEOUT requirement even where the CLI does not.
- Add a unit test asserting force always yields a params object containing TO and TIMEOUT.
When it happens
Trigger: Calling failover with failoverParams.force() (or force(true)) but omitting to(host,port) or timeout(duration); e.g. FailoverParams.failoverParams().force().build() without TO/TIMEOUT.
Common situations: Translating a CLI FAILOVER FORCE invocation (which needs no TO on a replica) directly into the client API without adding TO and TIMEOUT; copying force() from examples that also set TO/TIMEOUT out of frame; building params conditionally where TO/TIMEOUT branches were not taken.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Cluster retry deadline exceeded.
- Must choose exactly one filter in
- Cluster mode only supports SCAN command with MATCH pattern…
- HashImport ' ' expects values but got
- Support only execute to replica in ClusterCommandExecutor
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/21f46e8b2cfef8e8.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/params/FailoverParams.java:54
this.force = true;
return this;
}
public FailoverParams timeout(long timeout) {
this.timeout = timeout;
return this;
}
@Override
public void addParams(CommandArguments args) {
if (to != null) {
args.add(Keyword.TO).add(to.getHost()).add(to.getPort());
}
if (force) {
if (to == null || timeout == null) {
throw new IllegalArgumentException("FAILOVER with force option requires both a timeout and target HOST and IP.");
}
args.add(Keyword.FORCE);
}
if (timeout != null) {
args.add(Keyword.TIMEOUT).add(timeout);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FailoverParams that = (FailoverParams) o;
return force == that.force && Objects.equals(to, that.to) && Objects.equals(timeout, that.timeout);
}
View on GitHub (pinned to 6dac31d4c2)