{"record":{"id":"5b9ba45ff817851a","repo":"apache/dubbo","slug":"failed-to-get-extension-s-name-from-url-url","errorCode":null,"errorMessage":"Failed to get extension (%s) name from url (${url}) use keys(%s)","messagePattern":"Failed to get extension \\((.+?)\\) name from url \\((.+?)\\) use keys\\((.+?)\\)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java","lineNumber":66,"sourceCode":"\n    private static final String CODE_CLASS_DECLARATION = \"public class %s$Adaptive implements %s {\\n\";\n\n    private static final String CODE_METHOD_DECLARATION = \"public %s %s(%s) %s {\\n%s}\\n\";\n\n    private static final String CODE_METHOD_ARGUMENT = \"%s arg%d\";\n\n    private static final String CODE_METHOD_THROWS = \"throws %s\";\n\n    private static final String CODE_UNSUPPORTED =\n            \"throw new UnsupportedOperationException(\\\"The method %s of interface %s is not adaptive method!\\\");\\n\";\n\n    private static final String CODE_URL_NULL_CHECK =\n            \"if (arg%d == null) throw new IllegalArgumentException(\\\"url == null\\\");\\n%s url = arg%d;\\n\";\n\n    private static final String CODE_EXT_NAME_ASSIGNMENT = \"String extName = %s;\\n\";\n\n    private static final String CODE_EXT_NAME_NULL_CHECK = \"if(extName == null) \"\n            + \"throw new IllegalStateException(\\\"Failed to get extension (%s) name from url (\\\" + url.toString() + \\\") use keys(%s)\\\");\\n\";\n\n    private static final String CODE_INVOCATION_ARGUMENT_NULL_CHECK =\n            \"if (arg%d == null) throw new IllegalArgumentException(\\\"invocation == null\\\"); \"\n                    + \"String methodName = arg%d.getMethodName();\\n\";\n\n    private static final String CODE_SCOPE_MODEL_ASSIGNMENT =\n            \"ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), %s.class);\\n\";\n    private static final String CODE_EXTENSION_ASSIGNMENT =\n            \"%s extension = (%<s)scopeModel.getExtensionLoader(%s.class).getExtension(extName);\\n\";\n\n    private static final String CODE_EXTENSION_METHOD_INVOKE_ARGUMENT = \"arg%d\";\n\n    private final Class<?> type;\n\n    private final String defaultExtName;\n\n    public AdaptiveClassCodeGenerator(Class<?> type, String defaultExtName) {\n        this.type = type;","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/AdaptiveClassCodeGenerator.java#L48-L84","documentation":"This is a generated-code template (CODE_EXT_NAME_NULL_CHECK) emitted into the adaptive class. At runtime, the generated $Adaptive class throws IllegalStateException when the extension name cannot be resolved from the URL using the adaptive keys. This means URL.getParameter(key) / getMethodParameter(key) returned null (and no default extension name was configured), so Dubbo cannot determine which concrete extension to load.","triggerScenarios":"At runtime, calling a @Adaptive method where the URL lacks all of the parameter keys that the @Adaptive annotation specifies. The code tries url.getParameter(\"key1\"), then \"key2\", etc., and if all return null and there is no defaultExtName, extName stays null and this fires.","commonSituations":"A Dubbo URL is missing the protocol/extension-selection parameter. For example calling an adaptive method on a URL that has no \"protocol\" key and the SPI has no default extension name. Happens when URLs are hand-constructed without the required routing parameters, or when a config-center returns incomplete URL data.","solutions":["Inspect the exception message for the extension type and the keys tried, then add the missing parameter to the URL.","Set the required parameter on the URL: url = url.addParameter(\"<key>\", \"<extension-name>\").","If the SPI should have a default extension, configure one in the SPI config file (META-INF/dubbo/...) so defaultExtName is non-null.","Check that the @Adaptive annotation's value() lists the correct parameter keys."],"exampleFix":"// before\nURL url = URL.valueOf(\"dubbo://127.0.0.1:20880/Service\");\nadaptiveMethod(url); // ext name unresolvable\n\n// after\nURL url = URL.valueOf(\"dubbo://127.0.0.1:20880/Service\")\n    .addParameter(\"loadbalance\", \"random\");\nadaptiveMethod(url);","handlingStrategy":"validation","validationCode":"String[] keys = adaptiveAnnotation.value();\nboolean resolvable = false;\nfor (String k : keys) {\n    if (url.getParameter(k) != null) { resolvable = true; break; }\n}\nif (!resolvable && defaultExtName == null) {\n    // extension name cannot be resolved — fix URL or set default\n}","typeGuard":"static boolean canResolveExtensionName(URL url, String[] keys) {\n    if (url == null) return false;\n    return Arrays.stream(keys).anyMatch(k -> url.getParameter(k) != null);\n}","tryCatchPattern":"try {\n    adaptiveMethod(url);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Failed to get extension\")) {\n        url = url.addParameter(keys[0], \"default\");\n        adaptiveMethod(url);\n    } else throw e;\n}","preventionTips":["Ensure URLs carry the parameters listed in the @Adaptive annotation.","Configure a default extension name in the SPI config so extName is never null.","Validate URL parameters before calling adaptive methods."],"tags":["spi","adaptive-extension","code-generation","extension-resolution","url"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}