{"record":{"id":"a65eded0144bedf7","repo":"apache/dubbo","slug":"url-missing-protocol","errorCode":null,"errorMessage":"url missing protocol: \"{}\"","messagePattern":"url missing protocol: \"(.+?)\"","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLAddress.java","lineNumber":212,"sourceCode":"            } else {\n                port = Integer.parseInt(decodeStr.substring(i + 1));\n                host = decodeStr.substring(0, i);\n            }\n        } else {\n            host = decodeStr;\n        }\n\n        return new URLAddress(host, port, rawAddress);\n    }\n\n    private static PathURLAddress createPathURLAddress(String decodeStr, String rawAddress, String defaultProtocol) {\n        String protocol = defaultProtocol;\n        String path = null, username = null, password = null, host = null;\n        int port = 0;\n        int i = decodeStr.indexOf(\"://\");\n        if (i >= 0) {\n            if (i == 0) {\n                throw new IllegalStateException(\"url missing protocol: \\\"\" + decodeStr + \"\\\"\");\n            }\n            protocol = decodeStr.substring(0, i);\n            decodeStr = decodeStr.substring(i + 3);\n        } else {\n            // case: file:/path/to/file.txt\n            i = decodeStr.indexOf(\":/\");\n            if (i >= 0) {\n                if (i == 0) {\n                    throw new IllegalStateException(\"url missing protocol: \\\"\" + decodeStr + \"\\\"\");\n                }\n                protocol = decodeStr.substring(0, i);\n                decodeStr = decodeStr.substring(i + 1);\n            }\n        }\n\n        i = decodeStr.indexOf('/');\n        if (i >= 0) {\n            path = decodeStr.substring(i + 1);","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLAddress.java#L194-L230","documentation":"Thrown by URLAddress.createPathURLAddress when parsing a path-style Dubbo URL whose decoded string begins with '://' — i.e. the protocol segment before '://' is empty. Dubbo URL strings must carry a non-empty protocol (e.g. 'dubbo', 'zookeeper', 'rest') before the '://' separator. The parser splits on '://' and, finding it at index 0, rejects the input because no protocol can be extracted.","triggerScenarios":"URLAddress.parse(rawAddress, defaultProtocol, encoded) is invoked where rawAddress (after URL-decoding) contains PATH_SEPARATOR '/' AND starts with the literal '://' — for example '://10.0.0.1:20880/org.example.Foo' or a registry address '://127.0.0.1:2181'. This path is taken only when the decoded string contains '/' (isPathAddress == true); otherwise createURLAddress handles plain host:port strings.","commonSituations":"A Dubbo address or registry URL in dubbo.properties / XML / annotation has its protocol stripped or typoed to empty: '<dubbo:registry address=\"://127.0.0.1:2181\"/>', or a programmatic URL.valueOf(\"://host\") call. Also seen when a property placeholder (e.g. ${dubbo.protocol}) resolves to empty at runtime, or when an upstream config source emits a malformed URL with a leading colon-slash-slash.","solutions":["Inspect the full rawAddress printed in the message and prepend the correct protocol (e.g. 'dubbo://', 'zookeeper://', 'redis://') so the string is 'protocol://host:port/...'.","Check the originating config (dubbo.protocol / registry address property) for an empty or unset protocol placeholder and supply a value.","If the URL is built dynamically, guard the input: reject or default the protocol before calling URL.valueOf / URLAddress.parse when the string starts with '://'."],"exampleFix":"// before\n<dubbo:registry address=\"://127.0.0.1:2181\"/>\nURLAddress.parse(\"://10.0.0.1:20880/org.example.Foo\", \"dubbo\", false);\n\n// after\n<dubbo:registry address=\"zookeeper://127.0.0.1:2181\"/>\nURLAddress.parse(\"dubbo://10.0.0.1:20880/org.example.Foo\", \"dubbo\", false);","handlingStrategy":"validation","validationCode":"// Validate a Dubbo URL string before parsing\nString url = \"...\"; // the address\nif (url == null || url.startsWith(\"://\") || url.startsWith(\":/\")) {\n    throw new IllegalArgumentException(\"Dubbo URL must start with a non-empty protocol, e.g. 'dubbo://...': \" + url);\n}\nURLAddress.parse(url, defaultProtocol, encoded);","typeGuard":"// True when the URL string carries a non-empty protocol segment\nstatic boolean hasProtocol(String dubboUrl) {\n    if (dubboUrl == null) return false;\n    int i = dubboUrl.indexOf(\"://\");\n    if (i > 0) return true;            // protocol present before ://\n    int j = dubboUrl.indexOf(\":/\");     // file:/path style\n    return j > 0;\n}","tryCatchPattern":null,"preventionTips":["Always include a protocol token (dubbo://, zookeeper://, rest://) in registry/address configuration.","Resolve property placeholders for the protocol and assert they are non-empty before assembling the URL.","Add a startup validator that rejects addresses beginning with '://' or ':/'."],"tags":["url-parsing","configuration","dubbo-url","protocol"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}