signalapp/Signal-Server · error · InvalidAuthorizationHeaderException

Blank header

Error message

Blank header

What it means

BasicAuthorizationHeader.fromString parses a Basic Authorization header and throws InvalidAuthorizationHeaderException("Blank header") when the header value is null, empty, or whitespace only. The library requires a non-blank header string before any parsing.

Solutions

  1. Ensure the client sends 'Authorization: Basic <base64(user:pass)>' with a non-empty value
  2. Check the server filter/extractor reads the correct header name
  3. Return HTTP 401 to prompt the client to resend credentials instead of crashing on parse

Example fix

// before
BasicAuthorizationHeader.fromStrings(request.getHeader("Auth"));
// after
String h = request.getHeader(HttpHeaders.AUTHORIZATION);
if (h == null || h.isBlank()) throw new NotAuthorizedException("Basic");
BasicAuthorizationHeader.fromString(h);
Defensive patterns

Strategy: validation

Validate before calling

if (header == null || header.isBlank()) { throw new NotAuthorizedException("Basic realm=\"signal\""); }

Try / catch

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

Prevention

When it happens

Trigger: Calling BasicAuthorizationHeader.fromString(null), fromString(""), or fromString(" "); a client sending an Authorization header with no value after the header name.

Common situations: Reverse proxies stripping the Authorization header; HTTP clients that send the header name with an empty value; code reading the wrong header name and getting null.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

import org.apache.commons.lang3.StringUtils;
import org.whispersystems.textsecuregcm.util.Pair;

public class BasicAuthorizationHeader {

  private final String username;
  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)));

View on GitHub (pinned to 100ab61c82)