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

  1. Inspect the wrapped 'Last error' cause: for timeouts raise the method/invocation timeout; for connection errors fix provider reachability.
  2. If the operation is idempotent and benefits from retry, switch the cluster to 'failover' and set appropriate retries.
  3. 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

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


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/a26a8f72d215a4fd. Report an issue: GitHub.