zhisheng17/flink-learning · error · MalformedURLException

invalid elasticsearch hosts format

Error message

invalid elasticsearch hosts format

What it means

The ES7 ESSinkUtil.getEsAddresses mirrors the ES6 version: it splits the hosts string on commas and requires each token to be a URL or 'host:port'. A token without a port and not parseable as a URL throws MalformedURLException('invalid elasticsearch hosts format').

Source

Thrown at flink-learning-connectors/flink-learning-connectors-es/flink-learning-connectors-es7/src/main/java/com/zhisheng/connectors/es7/util/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. Append the port to each host, e.g. 'es-node:9200'
  2. Use full URLs with scheme, e.g. 'http://es-node:9200'
  3. Pre-validate the hosts string (each comma-separated part must contain ':' or a scheme) before calling getEsAddresses

Example fix

// before
"elasticsearch.hosts": "es-master"
// after
"elasticsearch.hosts": "es-master:9200"
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidEs7Hosts(String hosts) {
    if (hosts == null || hosts.isBlank()) return false;
    return Arrays.stream(hosts.split(","))
        .allMatch(h -> h.contains(":") || h.startsWith("http"));
}

Type guard

boolean hasPortOrScheme(String host) {
    return host != null && host.chars().filter(c -> c == ':').count() >= 1;
}

Try / catch

try {
    List<HttpHost> addresses = ESSinkUtil.getEsAddresses(hosts);
} catch (MalformedURLException e) {
    LOG.error("Invalid elasticsearch.hosts '{}': use host:port or http://host:port", hosts, e);
    throw e;
}

Prevention

When it happens

Trigger: Passing a hosts string like 'es-node' or 'a,b:9200' to getEsAddresses for the Elasticsearch 7 sink — any comma-separated element without a ':' separator that also fails new URL(host).

Common situations: Forgetting the 9200 port in application config, hostname-only entries from Kubernetes service names, or migrating config from other ES clients that accept bare hostnames.

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/d1a6769e1e921e2e. Report an issue: GitHub.