elastic/elasticsearch · error · IllegalStateException
cloudId {} does not contain a valid port number
Error message
cloudId {} does not contain a valid port number What it means
When the decoded cloudId's domain segment contains a ':port' suffix, the port substring must parse as an integer. If Integer.parseInt throws NumberFormatException, RestClient wraps it with this IllegalStateException naming the offending cloudId, since a non-numeric port makes the target HttpHost unconstructable.
Source
Thrown at client/rest/src/main/java/org/elasticsearch/client/RestClient.java:185
String decoded = new String(Base64.getDecoder().decode(cloudId), UTF_8);
// once decoded the parts are separated by a $ character.
// they are respectively domain name and optional port, elasticsearch id, kibana id
String[] decodedParts = decoded.split("\\$");
if (decodedParts.length != 3) {
throw new IllegalStateException("cloudId " + cloudId + " did not decode to a cluster identifier correctly");
}
// domain name and optional port
String[] domainAndMaybePort = decodedParts[0].split(":", 2);
String domain = domainAndMaybePort[0];
int port;
if (domainAndMaybePort.length == 2) {
try {
port = Integer.parseInt(domainAndMaybePort[1]);
} catch (NumberFormatException nfe) {
throw new IllegalStateException("cloudId " + cloudId + " does not contain a valid port number");
}
} else {
port = 443;
}
String url = decodedParts[1] + "." + domain;
return builder(new HttpHost(url, port, "https"));
}
/**
* Returns a new {@link RestClientBuilder} to help with {@link RestClient} creation.
* Creates a new builder instance and sets the hosts that the client will send requests to.
* <p>
* Prefer this to {@link #builder(HttpHost...)} if you have metadata up front about the nodes.
* If you don't either one is fine.
*/
public static RestClientBuilder builder(Node... nodes) {
return new RestClientBuilder(nodes == null ? null : Arrays.asList(nodes));View on GitHub (pinned to db6a809a66)
Solutions
- Re-copy the cloudId from Elastic Cloud — the port is managed by the platform and should always be numeric.
- If you must construct the host manually, bypass cloudId and use builder(new HttpHost(host, port, "https")).
- Validate the port segment parses before calling builder if you synthesize cloudIds programmatically.
Example fix
// before
RestClient.builder(badCloudIdWithNonNumericPort);
// after
RestClient.builder(new HttpHost("xyz.found.io", 9243, "https")); // or re-copy the cloudId Defensive patterns
Strategy: validation
Validate before calling
// If you synthesize cloudIds, validate the port segment parses before calling builder:
String decoded = new String(Base64.getDecoder().decode(payload));
String[] parts = decoded.split("\\$");
if (parts[0].contains(":")) Integer.parseInt(parts[0].split(":",2)[1]); // throws early with context Try / catch
try { RestClient.builder(cloudId); } catch (IllegalStateException e) { /* fall back to builder(new HttpHost(host, port, "https")) */ } Prevention
- Prefer the platform-provided cloudId; its port is always numeric.
- If you need a custom host/port, use builder(HttpHost) directly.
- Validate synthesized cloudIds before constructing the client.
When it happens
Trigger: A cloudId whose first '$'-segment is 'host:abc' (non-numeric port); a deployment with a malformed port field; a hand-edited cloudId that corrupted the port.
Common situations: Custom/edited cloudId; a deployment export bug producing a non-numeric port; locale-specific decimal separators accidentally injected.
Related errors
- cloudId {} must begin with a human readable identifier follo
- cloudId {} did not decode to a cluster identifier correctly
- hosts must not be null nor empty
- nodes must not be null or empty
- Can't create extra config file from {} for {} as it does not
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/361a37323d1b3eb6.
Report an issue: GitHub.