{"record":{"id":"7517559768598395","repo":"apache/dubbo","slug":"failed-to-forking-invoke-provider-selected-but","errorCode":null,"errorMessage":"Failed to forking invoke provider {selected}, but no luck to perform the invocation. Last error is: {e.getMessage()}","messagePattern":"Failed to forking invoke provider (.+?), but no luck to perform the invocation\\. Last error is: (.+?)","errorType":"exception","errorClass":"RpcException","httpStatus":null,"severity":"error","filePath":"dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java","lineNumber":120,"sourceCode":"                                executor)\n                        .whenComplete((v, t) -> {\n                            if (t == null) {\n                                ref.offer(v);\n                            } else {\n                                int value = count.incrementAndGet();\n                                if (value >= selected.size()) {\n                                    ref.offer(t);\n                                }\n                            }\n                        });\n            });\n            try {\n                Object ret = ref.poll(timeout, TimeUnit.MILLISECONDS);\n                if (ret instanceof Throwable) {\n                    Throwable e = ret instanceof CompletionException\n                            ? ((CompletionException) ret).getCause()\n                            : (Throwable) ret;\n                    throw new RpcException(\n                            e instanceof RpcException ? ((RpcException) e).getCode() : RpcException.UNKNOWN_EXCEPTION,\n                            \"Failed to forking invoke provider \" + selected\n                                    + \", but no luck to perform the invocation. \" + \"Last error is: \" + e.getMessage(),\n                            e.getCause() != null ? e.getCause() : e);\n                }\n                return (Result) ret;\n            } catch (InterruptedException e) {\n                throw new RpcException(\n                        \"Failed to forking invoke provider \" + selected + \", \"\n                                + \"but no luck to perform the invocation. Last error is: \" + e.getMessage(),\n                        e);\n            }\n        } finally {\n            // clear attachments which is binding to current thread.\n            RpcContext.getClientAttachment().clearAttachments();\n        }\n    }\n}","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java#L102-L138","documentation":"Thrown by ForkingClusterInvoker.doInvoke() when all forked (parallel) invocations fail — the bounded queue receives a Throwable once the failure count reaches the number of selected providers — or when the result poll is interrupted. The forking strategy invokes N providers in parallel and returns the first success; if none succeed, the last error is surfaced.","triggerScenarios":"Using cluster='forking' with 'forks' parallel providers; every forked invocation throws, so count reaches selected.size() and a Throwable is offered to the queue, which is then unwrapped and rethrown. Also thrown if the poll(timeout) is interrupted (InterruptedException).","commonSituations":"All forked providers fail within the fork window; the configured 'forks' exceeds available healthy providers; timeout shorter than the slowest fork so the queue reports failure; the calling thread is interrupted during the poll.","solutions":["Inspect the unwrapped 'Last error' cause — typically all forked providers failed; fix the underlying provider/network issue.","Tune 'forks' (number of parallel invocations) and 'timeout' so enough healthy providers are tried within the window.","If interrupted (InterruptedException branch), ensure the caller is not being cancelled mid-RPC and align timeouts with the forking window."],"exampleFix":"# before: forks and timeout defaults cause all forks to fail / interrupt\n@DubboReference(cluster = \"forking\")\nprivate QueryService queryService;\n\n# after: tune forks + timeout for the parallel fan-out\n@DubboReference(cluster = \"forking\", forks = 3, timeout = 2000)\nprivate QueryService queryService;","handlingStrategy":"try-catch","validationCode":"// Pre-flight for forking cluster: ensure enough providers and a sane timeout\nint forks = url.getParameter(FORKS_KEY, DEFAULT_FORKS);\nif (forks <= 0 || directory.getAllInvokers().size() < 1) {\n    return fallback();\n}\n// confirm timeout is long enough for the parallel fan-out window","typeGuard":null,"tryCatchPattern":"try {\n    return forkingService.query(q);\n} catch (RpcException e) {\n    if (e.getMessage().contains(\"Failed to forking invoke\")) {\n        // all forks failed or the poll was interrupted; degrade or alert\n        log.error(\"Forking invoke failed: \" + e.getMessage());\n        return fallback();\n    }\n    throw e;\n}","preventionTips":["Tune forks and timeout so enough healthy providers are tried within the window.","Ensure the calling thread is not interrupted during the fork poll.","Use forking only for read/query operations that tolerate parallel fan-out."],"tags":["cluster","forking","parallel","timeout","no-provider"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}