{"record":{"id":"04833a4ecb51fe2b","repo":"apache/dubbo","slug":"url-missing-protocol-fullurlstr","errorCode":null,"errorMessage":"url missing protocol: \"${fullURLStr}\"","messagePattern":"url missing protocol: \"(.+?)\"","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/URLStrParser.java","lineNumber":114,"sourceCode":"    /**\n     * @param fullURLStr  : fullURLString\n     * @param decodedBody : format: [protocol://][username:password@][host:port]/[path]\n     * @param parameters  :\n     * @return URL\n     */\n    private static URL parseURLBody(String fullURLStr, String decodedBody, Map<String, String> parameters) {\n        int starIdx = 0, endIdx = decodedBody.length();\n        // ignore the url content following '#'\n        int poundIndex = decodedBody.indexOf('#');\n        if (poundIndex != -1) {\n            endIdx = poundIndex;\n        }\n\n        String protocol = null;\n        int protoEndIdx = decodedBody.indexOf(\"://\");\n        if (protoEndIdx >= 0) {\n            if (protoEndIdx == 0) {\n                throw new IllegalStateException(\"url missing protocol: \\\"\" + fullURLStr + \"\\\"\");\n            }\n            protocol = decodedBody.substring(0, protoEndIdx);\n            starIdx = protoEndIdx + 3;\n        } else {\n            // case: file:/path/to/file.txt\n            protoEndIdx = decodedBody.indexOf(\":/\");\n            if (protoEndIdx >= 0) {\n                if (protoEndIdx == 0) {\n                    throw new IllegalStateException(\"url missing protocol: \\\"\" + fullURLStr + \"\\\"\");\n                }\n                protocol = decodedBody.substring(0, protoEndIdx);\n                starIdx = protoEndIdx + 1;\n            }\n        }\n\n        String path = null;\n        int pathStartIdx = indexOf(decodedBody, '/', starIdx, endIdx);\n        if (pathStartIdx >= 0) {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/URLStrParser.java#L96-L132","documentation":"Thrown by URLStrParser.parseURLBody as an IllegalStateException when the URL string contains the '://' separator at position 0, i.e. the protocol segment before '://' is empty. The parser cannot determine a protocol, so it rejects the malformed URL rather than guessing.","triggerScenarios":"Parsing a URL string that starts with '://' (e.g. \"://host:port/path\") via URLStrParser / valueOf paths; a URL built by concatenation where the protocol variable was empty before '://'; a config placeholder for the protocol that resolved to empty string.","commonSituations":"Config templating where ${protocol} is unset and yields '://host...'; string concatenation building a URL with an empty protocol field; copy-paste removing the protocol; environment/profile that fails to inject the protocol variable; malformed registry/address strings parsed at startup.","solutions":["Supply a non-empty protocol before '://' in the URL string (e.g. 'dubbo://', 'nacos://', 'zookeeper://').","Fix the config interpolation so the protocol variable resolves to a real value in the active profile.","Validate URL strings before parsing: assert they match <nonempty>:// before passing to URLStrParser."],"exampleFix":"// before\nString u = \"://\" + host + \":\" + port + \"/\" + path; // protocol empty -> throws\n\n// after\nString u = protocol + \"://\" + host + \":\" + port + \"/\" + path; // protocol non-empty","handlingStrategy":"validation","validationCode":"// Validate the URL shape before parsing\nif (url == null || url.startsWith(\"://\") || (url.contains(\"://\") && url.indexOf(\"://\") == 0)) {\n    throw new IllegalArgumentException(\"url missing protocol: \" + url);\n}\nURL parsed = URLStrParser.parseURL(url);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure config placeholders for the protocol (e.g. ${protocol}) resolve in every profile.","Validate URL strings match <nonempty>:// at config load time.","Build URLs by concatenation only with a guaranteed non-empty protocol constant."],"tags":["url","parser","config","validation","protocol"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}