zhisheng17/flink-learning · error · MalformedURLException

invalid elasticsearch hosts format

Error message

invalid elasticsearch hosts format

What it means

ESSinkUtil.getEsAddresses parses a hosts string like 'host1:9200,host2:9200' into HttpHost instances. Each comma-separated token must be either a full URL or contain 'host:port'. If a token has no port and is not a parseable URL, the method throws MalformedURLException('invalid elasticsearch hosts format').

Source

Thrown at flink-learning-connectors/flink-learning-connectors-es/flink-learning-connectors-es6/src/main/java/com/zhisheng/connectors/es6/utils/ESSinkUtil.java:65

     * 解析配置文件的 es hosts
     *
     * @param hosts
     * @return
     * @throws MalformedURLException
     */
    public static List<HttpHost> getEsAddresses(String hosts) throws MalformedURLException {
        String[] hostList = hosts.split(",");
        List<HttpHost> addresses = new ArrayList<>();
        for (String host : hostList) {
            if (host.startsWith("http")) {
                URL url = new URL(host);
                addresses.add(new HttpHost(url.getHost(), url.getPort()));
            } else {
                String[] parts = host.split(":", 2);
                if (parts.length > 1) {
                    addresses.add(new HttpHost(parts[0], Integer.parseInt(parts[1])));
                } else {
                    throw new MalformedURLException("invalid elasticsearch hosts format");
                }
            }
        }
        return addresses;
    }
}

View on GitHub (pinned to d731cee761)

Solutions

  1. Add the port to every host in the hosts string, e.g. 'localhost:9200'
  2. Prefix hosts with a scheme so they parse as URLs, e.g. 'http://localhost'
  3. Split on commas and validate each element contains ':' or a URL scheme before passing the string to getEsAddresses

Example fix

// before
getEsAddresses(env, "localhost");
// after
getEsAddresses(env, "localhost:9200");
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidEsHosts(String hosts) {
    if (hosts == null || hosts.isEmpty()) return false;
    for (String h : hosts.split(",")) {
        String s = h.trim();
        if (!(s.contains(":") || s.startsWith("http://") || s.startsWith("https://"))) return false;
    }
    return true;
}

Type guard

boolean isHostWithPort(String host) {
    return host != null && (host.contains(":") || host.matches("^https?://.+"));
}

Try / catch

try {
    List<HttpHost> addresses = ESSinkUtil.getEsAddresses(hosts);
} catch (MalformedURLException e) {
    throw new IllegalArgumentException("Bad ES hosts config '" + hosts + "': every host needs a port, e.g. host:9200", e);
}

Prevention

When it happens

Trigger: Calling getEsAddresses with a hosts string containing a bare token without a port, e.g. 'localhost' or 'es1,es2:9200' — any comma-separated element lacking a ':' and not parseable as a URL (no scheme like http://localhost).

Common situations: Config typos where the port was forgotten, copying hostnames from cluster discovery output without ports, or using hostname-only strings in flink conf/properties for the ES6 sink.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of zhisheng17/flink-learning@d731cee761 (2026-09-06). Data as JSON: /api/errors/7f818f642c3ab283. Report an issue: GitHub.