apache/dubbo · error · IllegalStateException

url missing protocol: "<url>"

Error message

url missing protocol: "<url>"

What it means

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 '://'.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/UrlUtils.java:645

                    if (j >= 0) {
                        String key = part.substring(0, j);
                        String value = part.substring(j + 1);
                        parameters.put(key, value);
                        // compatible with lower versions registering "default." keys
                        if (key.startsWith(DEFAULT_KEY_PREFIX)) {
                            parameters.putIfAbsent(key.substring(DEFAULT_KEY_PREFIX.length()), value);
                        }
                    } else {
                        parameters.put(part, part);
                    }
                }
            }
            url = url.substring(0, i);
        }
        i = url.indexOf("://");
        if (i >= 0) {
            if (i == 0) {
                throw new IllegalStateException("url missing protocol: \"" + url + "\"");
            }
            protocol = url.substring(0, i);
            url = url.substring(i + 3);
        } else {
            // case: file:/path/to/file.txt
            i = url.indexOf(":/");
            if (i >= 0) {
                if (i == 0) {
                    throw new IllegalStateException("url missing protocol: \"" + url + "\"");
                }
                protocol = url.substring(0, i);
                url = url.substring(i + 1);
            }
        }

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

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Inspect the exact URL printed in the message: everything before '://' is empty, so add the missing protocol (e.g. 'dubbo', 'zookeeper', 'nacos').
  2. Check that no config property/placeholder resolved to empty before being concatenated with '://'.
  3. Grep the configuration (application.properties, dubbo.properties, Spring XML, registry address) for the offending host string and supply a full 'protocol://host[:port]' value.
  4. If the value comes from a dynamic source, log it before calling URL.valueOf to find where the protocol is stripped.

Example fix

// before
<dubbo:registry address="://127.0.0.1:2181"/>
// after
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
Defensive patterns

Strategy: validation

Validate before calling

void assertValidDubboUrl(String url) {
    if (url == null || url.trim().isEmpty()) throw new IllegalArgumentException("empty url");
    String body = url.contains("?") ? url.substring(0, url.indexOf('?')) : url;
    int i = body.indexOf("://");
    if (i == 0) throw new IllegalArgumentException("url starts with '://' — protocol missing: " + url);
    if (i < 0) {
        int j = body.indexOf(":/");
        if (j == 0) throw new IllegalArgumentException("url starts with ':/' — protocol missing: " + url);
    }
}
// call before URL.valueOf(url)

Try / catch

try {
    URL url = URL.valueOf(addr);
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("url missing protocol")) {
        // log addr source, fail fast with actionable message
    }
    throw e;
}

Prevention

When it happens

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

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

Related errors


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