{"record":{"id":"7969704041ba364c","repo":"alibaba/nacos","slug":"illegal-url-path-expression-subpath","errorCode":null,"errorMessage":"Illegal url path expression : {subPath}","messagePattern":"Illegal url path expression : (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java","lineNumber":159,"sourceCode":"     * @param subPaths   api path\n     * @return URL string\n     */\n    public static String buildUrl(boolean isHttps, String serverAddr, String... subPaths) {\n        StringBuilder sb = new StringBuilder();\n        if (isHttps) {\n            sb.append(HTTPS_PREFIX);\n        } else {\n            sb.append(HTTP_PREFIX);\n        }\n        sb.append(serverAddr);\n        String pre = null;\n        for (String subPath : subPaths) {\n            if (StringUtils.isBlank(subPath)) {\n                continue;\n            }\n            Matcher matcher = CONTEXT_PATH_MATCH.matcher(subPath);\n            if (matcher.find()) {\n                throw new IllegalArgumentException(\"Illegal url path expression : \" + subPath);\n            }\n            if (pre == null || !pre.endsWith(\"/\")) {\n                if (subPath.startsWith(\"/\")) {\n                    sb.append(subPath);\n                } else {\n                    sb.append('/').append(subPath);\n                }\n            } else {\n                if (subPath.startsWith(\"/\")) {\n                    sb.append(subPath.replaceFirst(\"\\\\/\", \"\"));\n                } else {\n                    sb.append(subPath);\n                }\n            }\n            pre = subPath;\n        }\n        return sb.toString();\n    }","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java#L141-L177","documentation":"Thrown by HttpUtils.buildUrl() as an IllegalArgumentException when any individual subPath segment contains two or more consecutive forward slashes, matched by the regex (\\/)\\1+. This is the same pattern used by ValidatorUtils.checkContextPath (error 722) but applied to URL path segments during URL construction. Blank subPaths are skipped, but any non-blank subPath with '//' is rejected. The message includes the offending subPath.","triggerScenarios":"Calling HttpUtils.buildUrl(isHttps, serverAddr, subPaths) where one of the subPaths contains '//'. For example, buildUrl(false, \"host:8848\", \"/nacos//v3\") or buildUrl(false, \"host:8848\", \"a//b\").","commonSituations":"Programmatic URL construction that concatenates path segments without normalizing slashes; context paths that already end with '/' combined with resource paths that start with '/'; copy-paste from browser URLs that contain collapsed-path anomalies.","solutions":["Normalize each subPath segment to remove consecutive slashes before passing to buildUrl.","Ensure context path segments do not have trailing slashes when the next segment has a leading slash.","Use a URL-building utility that handles slash joining automatically."],"exampleFix":"// before\nString url = HttpUtils.buildUrl(false, \"127.0.0.1:8848\", \"/nacos//v3\", \"/config\");\n\n// after — normalize each segment\nString url = HttpUtils.buildUrl(false, \"127.0.0.1:8848\", \"/nacos/v3\", \"/config\");","handlingStrategy":"validation","validationCode":"for (String subPath : subPaths) {\n    if (subPath != null && subPath.contains(\"//\")) {\n        throw new IllegalArgumentException(\"subPath contains consecutive slashes: \" + subPath);\n    }\n}\nString url = HttpUtils.buildUrl(isHttps, serverAddr, subPaths);","typeGuard":null,"tryCatchPattern":"try {\n    url = HttpUtils.buildUrl(isHttps, serverAddr, subPaths);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Illegal url path expression\")) {\n        // Normalize all subPaths and retry\n        String[] normalized = Arrays.stream(subPaths)\n            .map(p -> p == null ? null : p.replaceAll(\"/+\", \"/\"))\n            .toArray(String[]::new);\n        url = HttpUtils.buildUrl(isHttps, serverAddr, normalized);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Normalize subPath segments with replaceAll(\"/+\", \"/\") before calling buildUrl.","Use a URL-join utility that handles leading/trailing slashes between segments.","Avoid constructing paths by string concatenation of slash-terminated fragments."],"tags":["http-client","validation","url-construction","context-path"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}