languagetool-org/languagetool · error · AuthException

Expected Basic Authentication

Error message

Expected Basic Authentication

What it means

Constructor guard in BasicAuthentication: the supplied Authorization header did not start with 'Basic ', so it is either missing or uses another auth scheme, and cannot be decoded as basic credentials.

Source

Thrown at languagetool-server/src/main/java/org/languagetool/server/BasicAuthentication.java:32

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
package org.languagetool.server;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class BasicAuthentication {
  private final String user;
  private final String password;

  public BasicAuthentication(String authHeader) {
    if (!authHeader.startsWith("Basic ")) {
      throw new AuthException("Expected Basic Authentication");
    }
    String authEncoded = authHeader.substring("Basic ".length());
    Charset cs = StandardCharsets.UTF_8;
    ByteBuffer authDecodedBytes = ByteBuffer.wrap(Base64.getDecoder().decode(authEncoded.getBytes(cs)));
    String authDecoded = cs.decode(authDecodedBytes).toString();
    String[] authParts = authDecoded.split(":", 2);
    if (authParts.length != 2 || authParts[0].trim().isEmpty() || authParts[1].trim().isEmpty()) {
      throw new AuthException("Expected Basic Authentication");
    }
    user = authParts[0];
    password = authParts[1];
  }

  public String getUser() {
    return user;
  }

  public String getPassword() {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Send 'Authorization: Basic <base64(user:password)>' exactly, with the 'Basic ' prefix.
  2. Switch the client's auth scheme to basic authentication.
  3. Verify no middleware rewrites or strips the Authorization header.
  4. Check capitalization/prefix handling; the check is case-sensitive ('Basic ' with capital B).

Example fix

// before
headers.set("Authorization", "Bearer eyJhbGci...")
// after
String cred = Base64.getEncoder().encodeToString("user:pass".getBytes(StandardCharsets.UTF_8));
headers.set("Authorization", "Basic " + cred);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!authHeader || !authHeader.startsWith('Basic ')) {
  throw new Error('Authorization header must use Basic scheme');
}

Type guard

function isBasicAuthHeader(h) { return typeof h === 'string' && h.startsWith('Basic '); }

Try / catch

try {
  BasicAuthentication auth = new BasicAuthentication(request.getHeader("Authorization"));
} catch (AuthException e) {
  response.sendError(401, "Provide Authorization: Basic <base64(user:pass)>");
}

Prevention

When it happens

Trigger: Sending an Authorization header with another scheme (Bearer, Token) or malformed casing/content, or an empty header, to an endpoint protected by this check.

Common situations: Clients configured for token/bearer auth against a server expecting basic auth; proxies stripping the scheme; hand-built headers missing the 'Basic ' prefix and space.

Understand the failure class

Related errors


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/c2dadc592fb534e4. Report an issue: GitHub.