languagetool-org/languagetool · error · AuthException
Expected Basic Authentication
Error message
Expected Basic Authentication
What it means
GET /v2/users/me authenticates the caller via the HTTP 'Authorization' header (Basic Authentication). handleGetUserInfoRequest checks the header first and throws an AuthException when it is absent, because user information can never be resolved without credentials.
Source
Thrown at languagetool-server/src/main/java/org/languagetool/server/ApiV2.java:360
/*
* Provide information on user that requests this, e.g. for add-on to acquire token + other information
* Expects user + password via HTTP Basic Auth
*/
private void handleGetUserInfoRequest(HttpExchange httpExchange, Map<String, String> parameters, HTTPServerConfig config) throws Exception {
if (httpExchange.getRequestMethod().equalsIgnoreCase("options")) {
ServerTools.setAllowOrigin(httpExchange, allowOriginUrl);
httpExchange.getResponseHeaders().put("Access-Control-Allow-Methods", Collections.singletonList("GET, OPTIONS"));
List<String> requestHeaders = httpExchange.getRequestHeaders().get("Access-Control-Request-Headers");
if (requestHeaders != null) {
httpExchange.getResponseHeaders().put("Access-Control-Allow-Headers", Collections.singletonList(String.join(", ", requestHeaders)));
}
httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_NO_CONTENT, -1);
ServerMetricsCollector.getInstance().logResponse(HttpURLConnection.HTTP_NO_CONTENT);
} else {
ensureGetMethod(httpExchange, "/users/me");
if (!httpExchange.getRequestHeaders().containsKey("Authorization")) {
throw new AuthException("Expected Basic Authentication");
}
String authParameter = parameters.getOrDefault("authMethod", "password");
if (!(authParameter.equals("password") ||
authParameter.equals("apiKey") ||
authParameter.equals("addonToken"))) {
throw new IllegalArgumentException("Unknown authMethod: " + authParameter);
}
String authHeader = httpExchange.getRequestHeaders().getFirst("Authorization");
BasicAuthentication basicAuthentication = new BasicAuthentication(authHeader);
String user = basicAuthentication.getUser();
String password = basicAuthentication.getPassword();
UserInfoEntry userInfo = null;
if (authParameter.equals("password")) {
userInfo = DatabaseAccess.getInstance().getUserInfoWithPassword(user, password);
} else if (authParameter.equals("addonToken")) {
userInfo = DatabaseAccess.getInstance().getUserInfoWithAddonToken(user, password);View on GitHub (pinned to 2e990059ce)
Solutions
- Add an Authorization: Basic base64(user:password) header to the request.
- Prefer the header over query-parameter credentials for /users/me, as the header is mandatory here.
- Check that redirects (302) preserve the Authorization header or re-attach it manually.
- Verify no proxy or CORS preflight configuration strips the header.
Example fix
// before curl https://server/v2/users/me?username=jane&token=abc // after curl -u jane:abc https://server/v2/users/me
Defensive patterns
Strategy: validation
Validate before calling
const headers = { Authorization: 'Basic ' + btoa(user + ':' + token) };
if (!headers.Authorization) throw new Error('users/me requires a Basic Authorization header'); Prevention
- Always set the Authorization header for /v2/users/me.
- Use credentials helpers (curl -u, HTTP basic auth options) rather than hand-built headers.
- Confirm proxies/redirects do not strip the Authorization header.
When it happens
Trigger: GET /v2/users/me with username/token only as query parameters and no Authorization header; HTTP clients stripping the header after redirects; API explorers that do not send Basic auth headers.
Common situations: Browsers or fetch calls omitting the header; reverse proxies removing Authorization headers; tests built against an anonymous server setup then pointed at the authenticated endpoint.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Missing 'text' or 'data' parameter
- Use parameter 'dicts', not 'dict' in GET /words API method.
- 'lang' parameter missing
- 'ruleId' parameter missing
- Rule '<ruleId>' not found for language <lang> (LanguageTool
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/315d0fea8ca5305e.
Report an issue: GitHub.