apache/dubbo · error · IllegalStateException

Stream method could not be overloaded.There are ${streamMeth

Error message

Stream method could not be overloaded.There are ${streamMethodCount} stream method signatures. method(${methodName})

What it means

ReflectionServiceDescriptor.initMethods() groups methods by name and counts how many resolve to SERVER_STREAM or BI_STREAM. Dubbo forbids overloading streaming methods of the same name because the dispatch layer keys on method name and cannot disambiguate two streaming variants. If more than one streaming overload exists for a name, registration is aborted at service-descriptor build time.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ReflectionServiceDescriptor.java:90

            MethodDescriptor methodDescriptor = new ReflectionMethodDescriptor(method);

            List<MethodDescriptor> methodModels = methods.computeIfAbsent(method.getName(), (k) -> new ArrayList<>(1));
            methodModels.add(methodDescriptor);
        }

        methods.forEach((methodName, methodList) -> {
            Map<String, MethodDescriptor> descMap = descToMethods.computeIfAbsent(methodName, k -> new HashMap<>());
            // not support BI_STREAM and SERVER_STREAM at the same time, for example,
            // void foo(Request, StreamObserver<Response>)  ---> SERVER_STREAM
            // StreamObserver<Response> foo(StreamObserver<Request>)   ---> BI_STREAM
            long streamMethodCount = methodList.stream()
                    .peek(methodModel -> descMap.put(methodModel.getParamDesc(), methodModel))
                    .map(MethodDescriptor::getRpcType)
                    .filter(rpcType -> rpcType == MethodDescriptor.RpcType.SERVER_STREAM
                            || rpcType == MethodDescriptor.RpcType.BI_STREAM)
                    .count();
            if (streamMethodCount > 1L)
                throw new IllegalStateException("Stream method could not be overloaded.There are " + streamMethodCount
                        + " stream method signatures. method(" + methodName + ")");
        });
    }

    public String getInterfaceName() {
        return interfaceName;
    }

    public Class<?> getServiceInterfaceClass() {
        return serviceInterfaceClass;
    }

    public Set<MethodDescriptor> getAllMethods() {
        Set<MethodDescriptor> methodModels = new HashSet<>();
        methods.forEach((k, v) -> methodModels.addAll(v));
        return methodModels;
    }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Rename one of the overloaded streaming methods so each streaming RPC has a unique name.
  2. If both signatures are genuinely needed, split them across two service interfaces rather than overloading.
  3. Confirm you did not accidentally duplicate a stream method (e.g. via interface inheritance merging two methods with the same name).

Example fix

// before (throws: two streaming methods named 'foo')
void foo(StreamObserver<Resp> so);
void foo(Req req, StreamObserver<Resp> so);

// after (unique names)
void foo(StreamObserver<Resp> so);
void fooWithReq(Req req, StreamObserver<Resp> so);
Defensive patterns

Strategy: validation

Validate before calling

// Before export, ensure no two streaming methods share a name.
Map<String, Long> streamCounts = Arrays.stream(iface.getMethods())
    .filter(m -> isStreamingShape(m))
    .collect(Collectors.groupingBy(Method::getName, Collectors.counting()));
streamCounts.entrySet().stream()
    .filter(e -> e.getValue() > 1)
    .findFirst()
    .ifPresent(e -> { throw new IllegalArgumentException("Duplicate stream method name: " + e.getKey()); });

Prevention

When it happens

Trigger: A service interface declares two or more methods with the same name that each classify as SERVER_STREAM or BI_STREAM (e.g. `void foo(StreamObserver<R>)` and `void foo(Req, StreamObserver<R>)`). The names collide; both are streaming; initMethods() throws during service descriptor construction.

Common situations: Adding a streaming overload to an existing streaming method while refactoring a Triple service. Auto-generating service interfaces from a schema that emits multiple streaming methods with identical names. Migrating from a unary API to streaming and forgetting to rename the old streaming method.

Related errors


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