apache/dubbo · error · IllegalStateException

method config error : return attribute must be set true when

Error message

method config error : return attribute must be set true when on-return or on-throw has been set.

What it means

Thrown by MethodConfig.convertMethodConfig2AsyncInfo() when an async callback (onreturn or onthrow) is configured but the method's 'return' attribute is set to false. The on-return and on-throw callbacks only make sense when the invocation actually returns a value or throws, so Dubbo rejects the contradictory config. This check fires during conversion of the method config into an AsyncMethodInfo.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/config/MethodConfig.java:279

                        }
                    } catch (Exception e) {
                        logger.info("Failed to override the property " + method.getName() + " in "
                                + this.getClass().getSimpleName()
                                + ", please make sure every property has getter/setter method provided.");
                    }
                }
            }
        }
    }

    public AsyncMethodInfo convertMethodConfig2AsyncInfo() {
        if ((getOninvoke() == null && getOnreturn() == null && getOnthrow() == null)) {
            return null;
        }

        // check config conflict
        if (Boolean.FALSE.equals(isReturn()) && (getOnreturn() != null || getOnthrow() != null)) {
            throw new IllegalStateException(
                    "method config error : return attribute must be set true when on-return or on-throw has been set.");
        }

        AsyncMethodInfo asyncMethodInfo = new AsyncMethodInfo();

        asyncMethodInfo.setOninvokeInstance(getOninvoke());
        asyncMethodInfo.setOnreturnInstance(getOnreturn());
        asyncMethodInfo.setOnthrowInstance(getOnthrow());

        try {
            if (StringUtils.isNotEmpty(oninvokeMethod)) {
                asyncMethodInfo.setOninvokeMethod(getMethodByName(getOninvoke().getClass(), oninvokeMethod));
            }

            if (StringUtils.isNotEmpty(onreturnMethod)) {
                asyncMethodInfo.setOnreturnMethod(getMethodByName(getOnreturn().getClass(), onreturnMethod));
            }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Set return="true" (the default) when onreturn or onthrow callbacks are specified.
  2. Remove the onreturn/onthrow callbacks if the method is genuinely fire-and-forget (return=false).
  3. Review the method config block and ensure callback attributes and return are consistent.

Example fix

// before
<dubbo:method name="doWork" return="false" onreturn="callback"/>
// after
<dubbo:method name="doWork" return="true" onreturn="callback"/>
Defensive patterns

Strategy: validation

Validate before calling

boolean hasCallback = methodConfig.getOnreturn() != null || methodConfig.getOnthrow() != null;
boolean returnDisabled = Boolean.FALSE.equals(methodConfig.isReturn());
if (hasCallback && returnDisabled) {
    throw new IllegalStateException("onreturn/onthrow require return=true");
}
methodConfig.convertMethodConfig2AsyncInfo();

Type guard

static boolean isAsyncConfigConsistent(MethodConfig m) {
    boolean hasCb = m.getOnreturn() != null || m.getOnthrow() != null;
    boolean retDisabled = Boolean.FALSE.equals(m.isReturn());
    return !(hasCb && retDisabled);
}

Try / catch

try {
    asyncInfo = methodConfig.convertMethodConfig2AsyncInfo();
} catch (IllegalStateException e) {
    if (e.getMessage().contains("return attribute must be set true")) {
        methodConfig.setReturn(true);
        asyncInfo = methodConfig.convertMethodConfig2AsyncInfo();
    } else throw e;
}

Prevention

When it happens

Trigger: Configuring a method with <dubbo:method name="..." return="false" onreturn="..."/> or onthrow while return is false. Programmatic equivalent: methodConfig.setReturn(false) together with setOnreturn(...)/setOnthrow(...).

Common situations: Enabling fire-and-forget (return=false) for performance but leaving an on-return callback attached from a prior copy-paste config. Migrating a sync method to async and forgetting to update return.

Related errors


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