{"record":{"id":"7eb5d12f5840119c","repo":"elastic/elasticsearch","slug":"pathprefix-is-malformed-consecutive-slashes-are-n","errorCode":null,"errorMessage":"pathPrefix is malformed. consecutive slashes are not allowed: [{}]","messagePattern":"pathPrefix is malformed\\. consecutive slashes are not allowed: \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"client/rest/src/main/java/org/elasticsearch/client/RestClientBuilder.java","lineNumber":220,"sourceCode":"     * it is not intended for other purposes and it should not be supplied in other scenarios.\n     *\n     * @throws NullPointerException if {@code pathPrefix} is {@code null}.\n     * @throws IllegalArgumentException if {@code pathPrefix} is empty or contains consecutive slashes.\n     */\n    public RestClientBuilder setPathPrefix(String pathPrefix) {\n        this.pathPrefix = cleanPathPrefix(pathPrefix);\n        return this;\n    }\n\n    public static String cleanPathPrefix(String pathPrefix) {\n        Objects.requireNonNull(pathPrefix, \"pathPrefix must not be null\");\n\n        if (pathPrefix.isEmpty()) {\n            throw new IllegalArgumentException(\"pathPrefix must not be empty\");\n        }\n\n        if (pathPrefix.contains(\"//\")) {\n            throw new IllegalArgumentException(\"pathPrefix is malformed. consecutive slashes are not allowed: [\" + pathPrefix + \"]\");\n        }\n\n        String cleanPathPrefix = pathPrefix;\n        if (cleanPathPrefix.startsWith(\"/\") == false) {\n            cleanPathPrefix = \"/\" + cleanPathPrefix;\n        }\n\n        // best effort to ensure that it looks like \"/base/path\" rather than \"/base/path/\"\n        if (cleanPathPrefix.endsWith(\"/\") && cleanPathPrefix.length() > 1) {\n            cleanPathPrefix = cleanPathPrefix.substring(0, cleanPathPrefix.length() - 1);\n        }\n        return cleanPathPrefix;\n    }\n\n    /**\n     * Sets the {@link NodeSelector} to be used for all requests.\n     * @throws NullPointerException if the provided nodeSelector is null\n     */","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/client/rest/src/main/java/org/elasticsearch/client/RestClientBuilder.java#L202-L238","documentation":"Validation in cleanPathPrefix: the prefix must not contain consecutive slashes (\"//\"). Such input would silently collapse or produce wrong paths, so it is rejected outright rather than normalized.","triggerScenarios":"Calling setPathPrefix(\"/base//path\") or any prefix where a user joined segments with extra slashes.","commonSituations":"Concatenating \"base/\" + \"/sub\" from config fields; copy-paste of a URL path with double slash; trailing-slash handling code that prepended a slash twice.","solutions":["Build the prefix from segments joined by a single slash, or collapse '//' to '/' yourself before passing.","Strip trailing slashes from each config segment before joining.","Run a quick sanity check: prefix.indexOf(\"//\") < 0."],"exampleFix":"// before\nbuilder.setPathPrefix(base + \"/\" + sub); // base ends with '/', sub starts with '/'\n// after\nString joined = (base + \"/\" + sub).replaceAll(\"/+\", \"/\");\nbuilder.setPathPrefix(joined);","handlingStrategy":"validation","validationCode":"String p = prefix.trim().replaceAll(\"/+\", \"/\");\nif (!p.isEmpty() && !p.contains(\"//\")) builder.setPathPrefix(p);","typeGuard":"prefix == null || (!prefix.isEmpty() && !prefix.contains(\"//\"))","tryCatchPattern":null,"preventionTips":["Always join path segments with a single slash.","Collapse accidental doubles before passing to the builder."],"tags":["rest-client","builder","path-prefix","validation"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}