{"record":{"id":"264658ce425ef93b","repo":"SonarSource/sonarqube","slug":"invalid-url-s","errorCode":null,"errorMessage":"Invalid URL, %s","messagePattern":"Invalid URL, (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java","lineNumber":160,"sourceCode":"      ApplicationHttpClient.Response response = githubApplicationHttpClient.post(baseUrl, token, endPoint, extraHeaders);\n      return handleResponse(response, endPoint, gsonClass);\n    } catch (Exception e) {\n      LOG.warn(FAILED_TO_REQUEST_BEGIN_MSG + endPoint, e);\n      return Optional.empty();\n    }\n  }\n\n  @Override\n  public void checkApiEndpoint(GithubAppConfiguration githubAppConfiguration) {\n    if (StringUtils.isBlank(githubAppConfiguration.getApiEndpoint())) {\n      throw new IllegalArgumentException(\"Missing URL\");\n    }\n\n    URI apiEndpoint;\n    try {\n      apiEndpoint = URI.create(githubAppConfiguration.getApiEndpoint());\n    } catch (IllegalArgumentException e) {\n      throw new IllegalArgumentException(\"Invalid URL, \" + e.getMessage());\n    }\n\n    if (!\"http\".equalsIgnoreCase(apiEndpoint.getScheme()) && !\"https\".equalsIgnoreCase(apiEndpoint.getScheme())) {\n      throw new IllegalArgumentException(\"Only http and https schemes are supported\");\n    } else if (!isValidGitHubUrl(apiEndpoint)) {\n      throw new IllegalArgumentException(\"Invalid GitHub URL\");\n    }\n  }\n\n  private static boolean isValidGitHubUrl(URI apiEndpoint) {\n    String host = apiEndpoint.getHost();\n    String path = apiEndpoint.getPath();\n    if (host == null) {\n      return false;\n    }\n\n    String lowerCaseHost = host.toLowerCase(Locale.ENGLISH);\n    // GitHub.com (official public GitHub)","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubApplicationClientImpl.java#L142-L178","documentation":"In checkApiEndpoint, after the blank check, the endpoint string is parsed with URI.create; if that throws IllegalArgumentException (invalid URI syntax), it is rethrown as \"Invalid URL, <reason>\". It means the configured GitHub API endpoint is not a syntactically valid URI (e.g. contains spaces or illegal characters) rather than the endpoint being unreachable.","triggerScenarios":"checkApiEndpoint invoked with an apiEndpoint string that URI.create cannot parse — spaces, unescaped special characters, missing scheme characters, control characters.","commonSituations":"Pasting a URL with a trailing space or newline from a config file; unescaped characters such as '|', '<', or a space inside the path; using a placeholder like '<your-github-url>' that was never substituted; URL copied with hidden non-ASCII characters.","solutions":["Inspect the configured API URL for stray whitespace, newlines, or unescaped special characters and fix it","Ensure the URL includes the scheme (https://) and is properly percent-encoded","Use the plain base API URL (e.g. https://api.github.com or https://<host>/api/v3) without placeholders","Trim the value programmatically before constructing GithubAppConfiguration"],"exampleFix":"// before\nString apiEndpoint = properties.getProperty(\"github.url\"); // \" https://github.example.com/api/v3 \" (leading/trailing spaces)\n// after\nString apiEndpoint = properties.getProperty(\"github.url\").trim(); // \"https://github.example.com/api/v3\"","handlingStrategy":"validation","validationCode":"// Java: validate URI syntax before calling checkApiEndpoint\ntry {\n  URI uri = new URI(apiEndpoint.trim());\n  if (uri.getScheme() == null || uri.getHost() == null) {\n    throw new IllegalArgumentException(\"GitHub API endpoint must be an absolute http(s) URL\");\n  }\n} catch (URISyntaxException e) {\n  throw new IllegalArgumentException(\"GitHub API endpoint is not a valid URL: \" + e.getMessage());\n}","typeGuard":"// Java: safe parse of the endpoint string\nstatic Optional<URI> parseApiEndpoint(String raw) {\n  try {\n    return Optional.of(URI.create(raw == null ? \"\" : raw.trim()));\n  } catch (IllegalArgumentException e) {\n    return Optional.empty();\n  }\n}","tryCatchPattern":"try {\n  githubApplicationClient.checkApiEndpoint(githubAppConfiguration);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Invalid URL, \")) {\n    throw new ConfigurationException(\"Fix the GitHub API URL syntax (no spaces/unescaped characters, include https://): \" + e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Trim whitespace/newlines from configuration values read from files or env before constructing the endpoint","Always include the scheme (https://) and percent-encode any special characters","Beware of unsubstituted placeholders like <your-host> in templated configs","Test the URL with new URI(value) or curl before saving the GitHub App integration"],"tags":["github","url","configuration","validation"],"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-14T05:17:10.506Z"}