{"record":{"id":"c3abb6aefcc7c090","repo":"apache/dubbo","slug":"url-missing-protocol-url","errorCode":null,"errorMessage":"url missing protocol: \"<url>\"","messagePattern":"url missing protocol: \"<url>\"","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/utils/UrlUtils.java","lineNumber":645,"sourceCode":"                    if (j >= 0) {\n                        String key = part.substring(0, j);\n                        String value = part.substring(j + 1);\n                        parameters.put(key, value);\n                        // compatible with lower versions registering \"default.\" keys\n                        if (key.startsWith(DEFAULT_KEY_PREFIX)) {\n                            parameters.putIfAbsent(key.substring(DEFAULT_KEY_PREFIX.length()), value);\n                        }\n                    } else {\n                        parameters.put(part, part);\n                    }\n                }\n            }\n            url = url.substring(0, i);\n        }\n        i = url.indexOf(\"://\");\n        if (i >= 0) {\n            if (i == 0) {\n                throw new IllegalStateException(\"url missing protocol: \\\"\" + url + \"\\\"\");\n            }\n            protocol = url.substring(0, i);\n            url = url.substring(i + 3);\n        } else {\n            // case: file:/path/to/file.txt\n            i = url.indexOf(\":/\");\n            if (i >= 0) {\n                if (i == 0) {\n                    throw new IllegalStateException(\"url missing protocol: \\\"\" + url + \"\\\"\");\n                }\n                protocol = url.substring(0, i);\n                url = url.substring(i + 1);\n            }\n        }\n\n        i = url.indexOf('/');\n        if (i >= 0) {\n            path = url.substring(i + 1);","sourceCodeStart":627,"sourceCodeEnd":663,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/UrlUtils.java#L627-L663","documentation":"Thrown by URL.valueOf(String) when the URL string contains the '://' separator at index 0, meaning there is no protocol segment before it (e.g. '://host:port/path'). Dubbo parses every registry, provider, and reference address through this method, so a malformed address aborts startup. The parser requires a non-empty protocol token before '://'.","triggerScenarios":"A URL string passed to URL.valueOf (directly or via registry address, <dubbo:registry address=...>, export URLs, subscribe URLs) starts with '://' so url.indexOf(\"://\") returns 0. Examples: '://127.0.0.1:2181', '://zookeeper://host' (double-protocol typo where the outer strips to '://...'), or a variable/placeholder that resolved to empty leaving '://host'.","commonSituations":"A registry/protocol address property was left blank or a placeholder (${registry.address}) was not substituted. A config concatenation bug produced '://' + host. Migrating from Spring XML to annotation config and forgetting the protocol prefix. Copy-pasting an address that already contained the scheme into a field that prepends another scheme.","solutions":["Inspect the exact URL printed in the message: everything before '://' is empty, so add the missing protocol (e.g. 'dubbo', 'zookeeper', 'nacos').","Check that no config property/placeholder resolved to empty before being concatenated with '://'.","Grep the configuration (application.properties, dubbo.properties, Spring XML, registry address) for the offending host string and supply a full 'protocol://host[:port]' value.","If the value comes from a dynamic source, log it before calling URL.valueOf to find where the protocol is stripped."],"exampleFix":"// before\n<dubbo:registry address=\"://127.0.0.1:2181\"/>\n// after\n<dubbo:registry address=\"zookeeper://127.0.0.1:2181\"/>","handlingStrategy":"validation","validationCode":"void assertValidDubboUrl(String url) {\n    if (url == null || url.trim().isEmpty()) throw new IllegalArgumentException(\"empty url\");\n    String body = url.contains(\"?\") ? url.substring(0, url.indexOf('?')) : url;\n    int i = body.indexOf(\"://\");\n    if (i == 0) throw new IllegalArgumentException(\"url starts with '://' — protocol missing: \" + url);\n    if (i < 0) {\n        int j = body.indexOf(\":/\");\n        if (j == 0) throw new IllegalArgumentException(\"url starts with ':/' — protocol missing: \" + url);\n    }\n}\n// call before URL.valueOf(url)","typeGuard":null,"tryCatchPattern":"try {\n    URL url = URL.valueOf(addr);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"url missing protocol\")) {\n        // log addr source, fail fast with actionable message\n    }\n    throw e;\n}","preventionTips":["Always specify protocol://host[:port] in registry and protocol addresses.","Resolve and log config placeholders before they reach URL.valueOf.","Add a startup self-check that validates all configured addresses have a protocol."],"tags":["url-parsing","config","registry","startup"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}