apache/dubbo · error · RpcException
Failfast invoke providers {invoker.getUrl()} {loadbalance.ge
Error message
Failfast invoke providers {invoker.getUrl()} {loadbalance.getClass().getSimpleName()} for service {getInterface().getName()} method {RpcUtils.getMethodName(invocation)} on consumer {NetUtils.getLocalHost()} use dubbo version {Version.getVersion()}, but no luck to perform the invocation. Last error is: {e.getMessage()} What it means
Thrown by FailfastClusterInvoker.doInvoke() when the single selected provider invocation fails with a non-business (non-biz) exception. The failfast strategy performs exactly one attempt (no retry) and is intended for non-idempotent writes; any network/timeout/system error is wrapped and rethrown with this message. Business (biz) exceptions are rethrown unchanged.
Source
Thrown at dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailfastClusterInvoker.java:53
* <a href="http://en.wikipedia.org/wiki/Fail-fast">Fail-fast</a>
*/
public class FailfastClusterInvoker<T> extends AbstractClusterInvoker<T> {
public FailfastClusterInvoker(Directory<T> directory) {
super(directory);
}
@Override
public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
throws RpcException {
Invoker<T> invoker = select(loadbalance, invocation, invokers, null);
try {
return invokeWithContext(invoker, invocation);
} catch (Throwable e) {
if (e instanceof RpcException && ((RpcException) e).isBiz()) { // biz exception.
throw (RpcException) e;
}
throw new RpcException(
e instanceof RpcException ? ((RpcException) e).getCode() : 0,
"Failfast invoke providers " + invoker.getUrl() + " "
+ loadbalance.getClass().getSimpleName()
+ " for service " + getInterface().getName()
+ " method " + RpcUtils.getMethodName(invocation) + " on consumer "
+ NetUtils.getLocalHost()
+ " use dubbo version " + Version.getVersion()
+ ", but no luck to perform the invocation. Last error is: " + e.getMessage(),
e.getCause() != null ? e.getCause() : e);
}
}
}
View on GitHub (pinned to 3a3043227f)
Solutions
- Inspect the wrapped 'Last error' cause: for timeouts raise the method/invocation timeout; for connection errors fix provider reachability.
- If the operation is idempotent and benefits from retry, switch the cluster to 'failover' and set appropriate retries.
- For genuinely non-idempotent writes, keep failfast but ensure the single attempt has sufficient timeout and the provider is healthy.
Example fix
# before: failfast times out on the single attempt
@DubboReference(cluster = "failfast") // default timeout too short
private OrderService orderService;
# after: raise timeout, or switch to failover if idempotent
@DubboReference(cluster = "failfast", timeout = 5000, methods = {@Method(name="createOrder", timeout=8000)})
private OrderService orderService; Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: confirm at least one provider and a sane timeout for failfast
if (CollectionUtils.isEmpty(directory.getAllInvokers())) {
return fallback();
}
// ensure timeout fits the operation before invoking with failfast (no retry) Try / catch
try {
return failfastService.createOrder(req);
} catch (RpcException e) {
if (!e.isBiz() && e.getMessage().contains("Failfast invoke")) {
// non-biz single-attempt failure; do NOT retry for non-idempotent writes
log.error("Failfast call failed: " + e.getMessage());
throw new OrderSubmitException("order submission failed", e);
}
throw e;
} Prevention
- Set a method timeout large enough for the single failfast attempt.
- Do not retry non-idempotent failfast calls on non-biz errors.
- Switch to failover only if the operation is idempotent.
When it happens
Trigger: A failfast-cluster RPC where the one selected provider throws a non-biz RpcException (timeout, connection refused, serialization error) or a Throwable. select() picks one invoker; invokeWithContext() fails; the catch wraps it.
Common situations: Timeout too short for the operation; provider temporarily unreachable; transient network error on the single attempt; using failfast for a call that needs retry (it will not retry).
Related errors
- Failed to invoke the method {methodName} in the service {get
- Failed to forking invoke provider {selected}, but no luck to
- INTERNAL_ERROR
- Directory of type {simpleName} already destroyed for service
- Failed to acquire read lock on invokerRefreshLock within tim
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/a26a8f72d215a4fd.
Report an issue: GitHub.