apache/dubbo · error · IllegalStateException

url missing protocol: "{}"

Error message

url missing protocol: "{}"

What it means

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.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/url/component/URLAddress.java:212

            } else {
                port = Integer.parseInt(decodeStr.substring(i + 1));
                host = decodeStr.substring(0, i);
            }
        } else {
            host = decodeStr;
        }

        return new URLAddress(host, port, rawAddress);
    }

    private static PathURLAddress createPathURLAddress(String decodeStr, String rawAddress, String defaultProtocol) {
        String protocol = defaultProtocol;
        String path = null, username = null, password = null, host = null;
        int port = 0;
        int i = decodeStr.indexOf("://");
        if (i >= 0) {
            if (i == 0) {
                throw new IllegalStateException("url missing protocol: \"" + decodeStr + "\"");
            }
            protocol = decodeStr.substring(0, i);
            decodeStr = decodeStr.substring(i + 3);
        } else {
            // case: file:/path/to/file.txt
            i = decodeStr.indexOf(":/");
            if (i >= 0) {
                if (i == 0) {
                    throw new IllegalStateException("url missing protocol: \"" + decodeStr + "\"");
                }
                protocol = decodeStr.substring(0, i);
                decodeStr = decodeStr.substring(i + 1);
            }
        }

        i = decodeStr.indexOf('/');
        if (i >= 0) {
            path = decodeStr.substring(i + 1);

View on GitHub (pinned to 3a3043227f)

Solutions

  1. 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/...'.
  2. Check the originating config (dubbo.protocol / registry address property) for an empty or unset protocol placeholder and supply a value.
  3. 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 '://'.

Example fix

// before
<dubbo:registry address="://127.0.0.1:2181"/>
URLAddress.parse("://10.0.0.1:20880/org.example.Foo", "dubbo", false);

// after
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
URLAddress.parse("dubbo://10.0.0.1:20880/org.example.Foo", "dubbo", false);
Defensive patterns

Strategy: validation

Validate before calling

// Validate a Dubbo URL string before parsing
String url = "..."; // the address
if (url == null || url.startsWith("://") || url.startsWith(":/")) {
    throw new IllegalArgumentException("Dubbo URL must start with a non-empty protocol, e.g. 'dubbo://...': " + url);
}
URLAddress.parse(url, defaultProtocol, encoded);

Type guard

// True when the URL string carries a non-empty protocol segment
static boolean hasProtocol(String dubboUrl) {
    if (dubboUrl == null) return false;
    int i = dubboUrl.indexOf("://");
    if (i > 0) return true;            // protocol present before ://
    int j = dubboUrl.indexOf(":/");     // file:/path style
    return j > 0;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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