{"record":{"id":"a4b4bf4e330bf5fc","repo":"languagetool-org/languagetool","slug":"invalid-userinfo-format-expected-user-password","errorCode":null,"errorMessage":"Invalid userInfo format, expected 'user:password': ","messagePattern":"Invalid userInfo format, expected 'user:password': ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/PasswordAuthenticator.java","lineNumber":46,"sourceCode":" * Authenticator that extracts username and password from URL, e.g.\n * from {@code http://user:password@myhost.org/path}\n * @since 2.7\n */\npublic class PasswordAuthenticator extends Authenticator {\n\n  @Override\n  @Nullable\n  protected PasswordAuthentication getPasswordAuthentication() {\n    if (getRequestingURL() == null) {\n      return null;\n    }\n    String userInfo = getRequestingURL().getUserInfo();\n    if (StringTools.isEmpty(userInfo)) {\n      return null;\n    }\n    String[] parts = userInfo.split(\":\");\n    if (parts.length != 2) {\n      throw new RuntimeException(\"Invalid userInfo format, expected 'user:password': \" + userInfo);\n    }\n    String username = parts[0];\n    String password = parts[1];\n    return new PasswordAuthentication(username, password.toCharArray());\n  }\n\n}\n","sourceCodeStart":28,"sourceCodeEnd":54,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/PasswordAuthenticator.java#L28-L54","documentation":"PasswordAuthenticator supplies credentials for HTTP requests made to a URL that embeds user info. It splits the URL's userInfo on ':' and expects exactly 'user:password'; any other shape throws this RuntimeException, because it cannot build a PasswordAuthentication from it.","triggerScenarios":"Java opening an HTTP connection (e.g. downloading language-model data) through a URL like https://host/path with userInfo set to something without exactly one colon — e.g. only a username, a token containing a colon-encoded password, or 'user:pass:extra'.","commonSituations":"Setting -Dhttp.proxyUser style credentials or embedding API tokens in URLs where the token itself contains ':' (colon must be percent-encoded as %3A), or forgetting the password part entirely.","solutions":["Format the URL userInfo as exactly 'user:password' with a single colon","Percent-encode any ':' inside the password as %3A before putting it in the URL","If only a token is needed, use 'token' as username with an empty-ish password field ('token:x') as required by the target service","Pass credentials via an Authenticator subclass or request headers instead of URL userInfo"],"exampleFix":"// before\nURL url = new URL(\"https://myuser:p@ss:word@example.com/model.zip\");\n// after\nURL url = new URL(\"https://myuser:p%40ss%3Aword@example.com/model.zip\");","handlingStrategy":"validation","validationCode":"String userInfo = url.getUserInfo();\nif (userInfo != null && userInfo.split(\":\").length != 2) {\n  throw new IllegalArgumentException(\"userInfo must be 'user:password'\");\n}","typeGuard":"boolean hasValidUserInfo(URL url) {\n  String ui = url == null ? null : url.getUserInfo();\n  return ui == null || ui.split(\":\").length == 2;\n}","tryCatchPattern":"try {\n  connection.getInputStream();\n} catch (RuntimeException e) {\n  if (e.getMessage().startsWith(\"Invalid userInfo format\")) {\n    log.error(\"Fix URL credentials: encode ':' in password as %3A\");\n    throw new IOException(e);\n  }\n  throw e;\n}","preventionTips":["Percent-encode ':' and '@' inside passwords in URLs","Prefer Authenticator/header-based auth over URL userInfo","Validate URL credentials before opening connections"],"tags":["http","authentication","url","credentials"],"backgroundTag":"invalid-url-format","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}