{"record":{"id":"5697a318187b3060","repo":"SonarSource/sonarqube","slug":"invalid-url-s-5697a3","errorCode":null,"errorMessage":"Invalid URL: '%s'.","messagePattern":"Invalid URL: '(.+?)'\\.","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java","lineNumber":134,"sourceCode":"    } finally {\n      almSettingCreationLock.unlock();\n    }\n  }\n\n  public void checkBitbucketCloudWorkspaceIDFormat(String workspaceId) {\n    if (!WORKSPACE_ID_PATTERN.matcher(workspaceId).matches()) {\n      throw BadRequestException.create(String.format(\n        \"Workspace ID '%s' has an incorrect format. Should only contain lowercase letters, numbers, dashes, and underscores.\",\n        workspaceId\n      ));\n    }\n  }\n\n  public void validateUrl(@Nullable String url) {\n    if (url == null || HttpUrl.parse(url) == null) {\n      LOG.warn(\"Rejected an invalid DevOps Platform URL\");\n      throw BadRequestException.create(format(\"Invalid URL: '%s'.\", url));\n    }\n  }\n\n  public void validateAzureName(String fieldName, String value) {\n    Matcher matcher = AZURE_NAME_INVALID_CHARS.matcher(value);\n    if (matcher.find()) {\n      String invalidChar = matcher.group();\n      if (LOG.isWarnEnabled()) {\n        LOG.warn(\"Rejected Azure DevOps name for field '{}': contains invalid character '{}'\", fieldName, invalidChar);\n      }\n      throw BadRequestException.create(format(\n        \"'%s' contains the invalid character '%s'. Azure DevOps names must not contain any of: \\\\ / : < > | ? *\",\n        fieldName, invalidChar));\n    }\n  }\n\n  public ProjectDto getProjectAsAdmin(DbSession dbSession, String projectKey) {\n    return getProject(dbSession, projectKey, ADMIN);\n  }","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsSupport.java#L116-L152","documentation":"AlmSettingsSupport.validateUrl rejects null or unparseable DevOps Platform URLs using OkHttp's HttpUrl.parse. It logs a warning and throws BadRequestException (HTTP 400) with the offending URL formatted into the message.","triggerScenarios":"Calling alm_settings create/update webservices (or v2 equivalents) with a url that is null, empty, or not a valid absolute HTTP(S) URL, e.g. 'github.com' without scheme or 'htp://typo'.","commonSituations":"Missing scheme ('mycompany.github.com'); typo'd scheme; trailing content like spaces; copy-paste from docs including markdown; passing empty string from automation.","solutions":["Provide an absolute URL including scheme, e.g. https://github.enterprise.example","Trim whitespace and remove surrounding quotes/special characters from the URL","Use http:// only for internal instances where TLS is not available","Validate the URL with a parser (e.g. OkHttp HttpUrl.parse) before submitting"],"exampleFix":"// before\nalmSettings.create(\"gh\", \"github.enterprise.example\");\n// after\nalmSettings.create(\"gh\", \"https://github.enterprise.example\");","handlingStrategy":"validation","validationCode":"boolean isValidUrl(String u) { return u != null && !u.isBlank() && okhttp3.HttpUrl.parse(u.trim()) != null; }\nif (!isValidUrl(url)) throw new IllegalArgumentException(\"Invalid URL: '\" + url + \"'.\");","typeGuard":"HttpUrl parsed = url == null ? null : HttpUrl.parse(url);\nif (parsed == null) { /* reject before API call */ }","tryCatchPattern":"try { support.validateUrl(url); } catch (BadRequestException e) { showUserFriendlyUrlError(); }","preventionTips":["Always include the https:// scheme in DevOps Platform URLs","Trim user input before submitting","Validate URLs client-side with a real URL parser, not regex"],"tags":["bad-request","url-validation","almsettings"],"backgroundTag":"invalid-url-format","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}