signalapp/Signal-Server · error · InvalidAuthorizationHeaderException

Invalid authorization header:

Error message

Invalid authorization header: 

What it means

fromString throws InvalidAuthorizationHeaderException("Invalid authorization header: <header>") when the header contains no space, so it cannot be split into an authorization type and credentials. Basic auth headers must be of the form "Basic <base64>".

Solutions

  1. Send the header as 'Basic ' + base64(username:password) including the space
  2. If using a token, use the appropriate Bearer auth provider instead
  3. Log/inspect the raw Authorization header to spot missing scheme

Example fix

// before
request.setHeader("Authorization", base64(user + ":" + pass));
// after
request.setHeader("Authorization", "Basic " + base64(user + ":" + pass));
Defensive patterns

Strategy: validation

Validate before calling

if (!header.contains(" ")) throw new IllegalArgumentException("Authorization header must be '<scheme> <credentials>'");

Try / catch

try { BasicAuthorizationHeader.fromString(header); } catch (InvalidAuthorizationHeaderException e) { throw new NotAuthorizedException("Basic"); }

Prevention

When it happens

Trigger: Header value like "Basic" alone, a raw base64 blob without the scheme, or a token pasted without the 'Basic ' prefix.

Common situations: Clients concatenating scheme and credentials without a space; missing the scheme entirely; some proxies rewriting the header.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09). Data as JSON: /api/errors/731e68722698cc9b. Report an issue: GitHub.

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/auth/BasicAuthorizationHeader.java:32

  private final byte deviceId;
  private final String password;

  private BasicAuthorizationHeader(final String username, final byte deviceId, final String password) {
    this.username = username;
    this.deviceId = deviceId;
    this.password = password;
  }

  public static BasicAuthorizationHeader fromString(final String header) throws InvalidAuthorizationHeaderException {
    try {
      if (StringUtils.isBlank(header)) {
        throw new InvalidAuthorizationHeaderException("Blank header");
      }

      final int spaceIndex = header.indexOf(' ');

      if (spaceIndex == -1) {
        throw new InvalidAuthorizationHeaderException("Invalid authorization header: " + header);
      }

      final String authorizationType = header.substring(0, spaceIndex);

      if (!"Basic".equals(authorizationType)) {
        throw new InvalidAuthorizationHeaderException("Unsupported authorization method: " + authorizationType);
      }

      final String credentials;

      try {
        credentials = new String(Base64.getDecoder().decode(header.substring(spaceIndex + 1)));
      } catch (final IndexOutOfBoundsException e) {
        throw new InvalidAuthorizationHeaderException("Missing credentials");
      }

      if (StringUtils.isEmpty(credentials)) {
        throw new InvalidAuthorizationHeaderException("Bad decoded value: " + credentials);

View on GitHub (pinned to 100ab61c82)