{"record":{"id":"3848f611cf0dc380","repo":"elastic/elasticsearch","slug":"cloudid-did-not-decode-to-a-cluster-identifier","errorCode":null,"errorMessage":"cloudId {} did not decode to a cluster identifier correctly","messagePattern":"cloudId (.+?) did not decode to a cluster identifier correctly","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"client/rest/src/main/java/org/elasticsearch/client/RestClient.java","lineNumber":173,"sourceCode":"     * @param cloudId a valid elastic cloud cloudId that will route to a cluster. The cloudId is located in\n     *                the user console https://cloud.elastic.co and will resemble a string like the following\n     *                optionalHumanReadableName:dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRlbGFzdGljc2VhcmNoJGtpYmFuYQ==\n     */\n    public static RestClientBuilder builder(String cloudId) {\n        // there is an optional first portion of the cloudId that is a human readable string, but it is not used.\n        if (cloudId.contains(\":\")) {\n            if (cloudId.indexOf(':') == cloudId.length() - 1) {\n                throw new IllegalStateException(\"cloudId \" + cloudId + \" must begin with a human readable identifier followed by a colon\");\n            }\n            cloudId = cloudId.substring(cloudId.indexOf(':') + 1);\n        }\n\n        String decoded = new String(Base64.getDecoder().decode(cloudId), UTF_8);\n        // once decoded the parts are separated by a $ character.\n        // they are respectively domain name and optional port, elasticsearch id, kibana id\n        String[] decodedParts = decoded.split(\"\\\\$\");\n        if (decodedParts.length != 3) {\n            throw new IllegalStateException(\"cloudId \" + cloudId + \" did not decode to a cluster identifier correctly\");\n        }\n\n        // domain name and optional port\n        String[] domainAndMaybePort = decodedParts[0].split(\":\", 2);\n        String domain = domainAndMaybePort[0];\n        int port;\n\n        if (domainAndMaybePort.length == 2) {\n            try {\n                port = Integer.parseInt(domainAndMaybePort[1]);\n            } catch (NumberFormatException nfe) {\n                throw new IllegalStateException(\"cloudId \" + cloudId + \" does not contain a valid port number\");\n            }\n        } else {\n            port = 443;\n        }\n\n        String url = decodedParts[1] + \".\" + domain;","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/client/rest/src/main/java/org/elasticsearch/client/RestClient.java#L155-L191","documentation":"After stripping the optional human-readable prefix and Base64-decoding, the cloudId must split on '$' into exactly three parts: domain[:port], elasticsearch id, kibana id. Any other count means the cloudId is structurally invalid and the cluster endpoint cannot be derived.","triggerScenarios":"Passing a cloudId whose decoded form has 2 or 4+ '$'-segments; a cloudId from a different Elastic deployment format; a corrupted/truncated Base64 that decodes to garbage without the expected separators.","commonSituations":"Wrong cloudId copied (e.g. from a Kibana-only or APM deployment); Base64 string trimmed or padded incorrectly; using a placeholder/example cloudId that is not a real one.","solutions":["Re-copy the cloudId verbatim from the Elastic Cloud deployment's 'Cloud ID' field.","Verify the Base64 decodes to a string with exactly two '$' separators.","If migrating deployments, generate a fresh cloudId for the new deployment."],"exampleFix":"// before\nRestClient.builder(\"not-valid-base64-payload\");\n// after\nRestClient.builder(\"MyDeploy:dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRlbGFzdGljc2VhcmNoJGtpYmFuYQ==\");","handlingStrategy":"validation","validationCode":"static boolean cloudIdDecodesToThreeParts(String cloudId) {\n    String payload = cloudId.contains(\":\") ? cloudId.substring(cloudId.indexOf(':') + 1) : cloudId;\n    try {\n        String decoded = new String(Base64.getDecoder().decode(payload));\n        return decoded.split(\"\\\\$\").length == 3;\n    } catch (IllegalArgumentException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try { RestClient.builder(cloudId); } catch (IllegalStateException e) { /* re-copy cloudId; it is malformed */ }","preventionTips":["Use the cloudId exactly as exported by Elastic Cloud.","Don't synthesize cloudIds by hand.","Validate the decoded structure at config load time."],"tags":["rest-client","cloud-id","config","validation"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}