languagetool-org/languagetool · error · RuntimeException
Invalid userInfo format, expected 'user:password':
Error message
Invalid userInfo format, expected 'user:password':
What it means
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.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/PasswordAuthenticator.java:46
* Authenticator that extracts username and password from URL, e.g.
* from {@code http://user:password@myhost.org/path}
* @since 2.7
*/
public class PasswordAuthenticator extends Authenticator {
@Override
@Nullable
protected PasswordAuthentication getPasswordAuthentication() {
if (getRequestingURL() == null) {
return null;
}
String userInfo = getRequestingURL().getUserInfo();
if (StringTools.isEmpty(userInfo)) {
return null;
}
String[] parts = userInfo.split(":");
if (parts.length != 2) {
throw new RuntimeException("Invalid userInfo format, expected 'user:password': " + userInfo);
}
String username = parts[0];
String password = parts[1];
return new PasswordAuthentication(username, password.toCharArray());
}
}
View on GitHub (pinned to 2e990059ce)
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
Example fix
// before
URL url = new URL("https://myuser:p@ss:word@example.com/model.zip");
// after
URL url = new URL("https://myuser:p%40ss%3Aword@example.com/model.zip"); Defensive patterns
Strategy: validation
Validate before calling
String userInfo = url.getUserInfo();
if (userInfo != null && userInfo.split(":").length != 2) {
throw new IllegalArgumentException("userInfo must be 'user:password'");
} Type guard
boolean hasValidUserInfo(URL url) {
String ui = url == null ? null : url.getUserInfo();
return ui == null || ui.split(":").length == 2;
} Try / catch
try {
connection.getInputStream();
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Invalid userInfo format")) {
log.error("Fix URL credentials: encode ':' in password as %3A");
throw new IOException(e);
}
throw e;
} Prevention
- Percent-encode ':' and '@' inside passwords in URLs
- Prefer Authenticator/header-based auth over URL userInfo
- Validate URL credentials before opening connections
When it happens
Trigger: 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'.
Common situations: 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.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Expected Basic Authentication
- Unknown authMethod: <authParameter>
- Expected Basic Authentication
- apiKey AND password was set, set only apiKey
- With 'username' set, you also need to specify 'apiKey'
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/a4b4bf4e330bf5fc.
Report an issue: GitHub.