elastic/elasticsearch · error · IllegalStateException

cloudId {} must begin with a human readable identifier follo

Error message

cloudId {} must begin with a human readable identifier followed by a colon

What it means

RestClient.builder(cloudId) accepts an optional human-readable prefix terminated by ':'. If a ':' is present but is the LAST character (nothing follows it), the cloudId is malformed — the Base64 payload that should follow the colon is empty, so parsing cannot proceed.

Source

Thrown at client/rest/src/main/java/org/elasticsearch/client/RestClient.java:163

        this.warningsHandler = strictDeprecationMode ? WarningsHandler.STRICT : WarningsHandler.PERMISSIVE;
        this.compressionEnabled = compressionEnabled;
        this.metaHeaderEnabled = metaHeaderEnabled;
        setNodes(nodes);
    }

    /**
     * Returns a new {@link RestClientBuilder} to help with {@link RestClient} creation.
     * Creates a new builder instance and sets the nodes that the client will send requests to.
     *
     * @param cloudId a valid elastic cloud cloudId that will route to a cluster. The cloudId is located in
     *                the user console https://cloud.elastic.co and will resemble a string like the following
     *                optionalHumanReadableName:dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRlbGFzdGljc2VhcmNoJGtpYmFuYQ==
     */
    public static RestClientBuilder builder(String cloudId) {
        // there is an optional first portion of the cloudId that is a human readable string, but it is not used.
        if (cloudId.contains(":")) {
            if (cloudId.indexOf(':') == cloudId.length() - 1) {
                throw new IllegalStateException("cloudId " + cloudId + " must begin with a human readable identifier followed by a colon");
            }
            cloudId = cloudId.substring(cloudId.indexOf(':') + 1);
        }

        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) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Re-copy the full cloudId from Elastic Cloud console (it contains the Base64 payload after the colon).
  2. Strip the human-readable prefix entirely if you only have the Base64 part — builder accepts a colon-less cloudId too.
  3. Validate the cloudId shape (contains ':' followed by non-empty Base64) before calling builder.

Example fix

// before
RestClient.builder("my-cluster:"); // empty payload after colon
// after
RestClient.builder("my-cluster:dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRlbGFzdGljc2VhcmNoJGtpYmFuYQ==");
Defensive patterns

Strategy: validation

Validate before calling

static boolean cloudIdHasPayload(String cloudId) {
    int ci = cloudId.indexOf(':');
    return ci < 0 || ci < cloudId.length() - 1; // colon-less, or colon followed by payload
}
if (!cloudIdHasPayload(cloudId)) throw new IllegalArgumentException("cloudId missing Base64 payload after colon");
RestClient.builder(cloudId);

Try / catch

try { RestClient.builder(cloudId); } catch (IllegalStateException e) { /* prompt user to re-copy cloudId from Elastic Cloud */ }

Prevention

When it happens

Trigger: Passing a cloudId string like 'my-cluster:' (colon with no Base64 after it); a truncated/copy-paste cloudId from the Elastic Cloud console; a cloudId whose prefix colon was added by mistake.

Common situations: User copies the human-readable label from Elastic Cloud but misses the Base64 portion; trailing whitespace or newline truncation; manual concatenation that drops the payload.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/433549e4dffa0d5e. Report an issue: GitHub.