signalapp/Signal-Server · error · WebApplicationException

Invalid combined unidentified sender access keys

Error message

Invalid combined unidentified sender access keys

What it means

CombinedUnidentifiedSenderAccessKeys parses a header of Base64-encoded combined unidentified sender access keys and throws WebApplicationException(401) if decoding fails (IllegalArgumentException) or the decoded array is null / not 16 bytes. The combined keys value must be exactly 16 bytes like a single access key (the XOR combination).

Solutions

  1. Compute the combined key as the protocol-specified 16-byte combination (XOR) of the sender's key and the recipient's unrestricted access key, not a concatenation
  2. Verify the decoded length is 16 before sending
  3. Re-derive from current identity keys if accounts re-registered

Example fix

// before
byte[] combined = concat(senderAccessKey, recipientAccessKey); // 32 bytes
// after
byte[] combined = new byte[16];
for (int i = 0; i < 16; i++) combined[i] = (byte)(senderAccessKey[i] ^ recipientAccessKey[i]);
Defensive patterns

Strategy: validation

Validate before calling

byte[] combined = Base64.getDecoder().decode(header);
if (combined == null || combined.length != 16) throw new IllegalArgumentException("combined access keys must decode to 16 bytes");

Try / catch

try { authFilter.call(); } catch (WebApplicationException e) { if (e.getResponse().getStatus() == 401) { /* recompute combined key */ } }

Prevention

When it happens

Trigger: Supplying a header whose Base64 decodes to a non-16-byte array; malformed Base64 (caught as IllegalArgumentException and wrapped with the same message context); sending per-recipient multi-byte concatenations instead of the 16-byte combined value.

Common situations: Client computes the combined key incorrectly (e.g. concatenates both 16-byte keys yielding 32 bytes); wrong Base64 alphabet or padding; stale key material after re-registration.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/auth/CombinedUnidentifiedSenderAccessKeys.java:20

 * Copyright 2021 Signal Messenger, LLC
 * SPDX-License-Identifier: AGPL-3.0-only
 */

package org.whispersystems.textsecuregcm.auth;

import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import java.util.Base64;

public class CombinedUnidentifiedSenderAccessKeys {
  private final byte[] combinedUnidentifiedSenderAccessKeys;

  public CombinedUnidentifiedSenderAccessKeys(String header) {
    try {
      this.combinedUnidentifiedSenderAccessKeys = Base64.getDecoder().decode(header);
      if (this.combinedUnidentifiedSenderAccessKeys == null || this.combinedUnidentifiedSenderAccessKeys.length != UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH) {
        throw new WebApplicationException("Invalid combined unidentified sender access keys", Status.UNAUTHORIZED);
      }
    } catch (IllegalArgumentException e) {
      throw new WebApplicationException(e, Response.Status.UNAUTHORIZED);
    }
  }

  public byte[] getAccessKeys() {
    return combinedUnidentifiedSenderAccessKeys;
  }
}

View on GitHub (pinned to 100ab61c82)