signalapp/Signal-Server · error · InvalidAuthorizationHeaderException

Badly-formatted credentials:

Error message

Badly-formatted credentials: 

What it means

Thrown while parsing a Basic authorization header when the Base64-decoded credentials do not match the expected 'username:password' format — specifically when the decoded string contains no ':' separator, so no username/password split can be performed. The faulting input is the Authorization header supplied by the client; it results in a 401 response via InvalidAuthorizationHeaderException.

Solutions

  1. Encode credentials as '<username>:<password>' where username is the account (e.g. +15551234567 or +15551234567.1 for a device)
  2. Base64-encode the full colon-joined string
  3. Check client credential construction joins with ':'

Example fix

// before
String creds = base64(password);
// after
String creds = base64(username + ":" + password);
Defensive patterns

Strategy: validation

Validate before calling

String decoded = new String(Base64.getDecoder().decode(credentialPart), StandardCharsets.UTF_8);
if (decoded.indexOf(':') == -1) throw new IllegalArgumentException("credentials must be 'username:password'");

Try / catch

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

Prevention

When it happens

Trigger: Base64 payload decodes to a single token with no colon, e.g. base64("somepassword") or a raw token passed as basic credentials.

Common situations: Clients treating the Signal auth password alone as full credentials instead of number:password; forgetting the deviceId/username portion.

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/22cf93b9dd0b9f3a. Report an issue: GitHub.

Appendix: source

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

        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);
      }

      final int credentialSeparatorIndex = credentials.indexOf(':');

      if (credentialSeparatorIndex == -1) {
        throw new InvalidAuthorizationHeaderException("Badly-formatted credentials: " + credentials);
      }

      final String usernameComponent = credentials.substring(0, credentialSeparatorIndex);

      final String username;
      final byte deviceId;
      {
        final Pair<String, Byte> identifierAndDeviceId =
            AccountAuthenticator.getIdentifierAndDeviceId(usernameComponent);

        username = identifierAndDeviceId.first();
        deviceId = identifierAndDeviceId.second();
      }

      final String password = credentials.substring(credentialSeparatorIndex + 1);

      if (StringUtils.isAnyBlank(username, password)) {
        throw new InvalidAuthorizationHeaderException("Username or password were blank");

View on GitHub (pinned to 100ab61c82)