signalapp/Signal-Server · error · WebApplicationException
access key length must be 16
Error message
access key length must be 16
What it means
Anonymous is a JAX-RS auth provider wrapper for unidentified-delivery access keys. It Base64-decodes the X-Signal-Access-Key header and rejects it with HTTP 401 unless the decoded byte array is exactly UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH (16) bytes. This prevents calls to profiles/messages from using malformed access keys.
Solutions
- Ensure the header is Base64 of the account's 16-byte unidentified access key (UUID-derived, per Signal protocol)
- Decode your Base64 client-side and assert the array length is 16 before sending
- Regenerate the access key from the correct account identity key material if it is stale or misderived
Example fix
// before String header = Base64.getEncoder().encodeToString(uuid.toString().getBytes()); // after byte[] key = UnidentifiedAccessUtil.getAccessKeyFor(acdUuid, identityKey); String header = Base64.getEncoder().encodeToString(key); // 16 bytes
Defensive patterns
Strategy: validation
Validate before calling
byte[] key = Base64.getDecoder().decode(header);
if (key.length != 16) throw new IllegalArgumentException("access key must be 16 bytes, got " + key.length); Try / catch
try { authFilter.call(); } catch (WebApplicationException e) { if (e.getResponse().getStatus() == 401) { /* regenerate access key and retry once */ } } Prevention
- Derive the access key with the standard 16-byte HMAC function from the identity key
- Unit-test that your encoded header decodes to exactly 16 bytes
- Never hand-roll the key derivation; use the client library
When it happens
Trigger: Sending a request with an access-key header whose Base64 value decodes to a byte array that is not 16 bytes long (e.g. 0 bytes, 8, 32 bytes).
Common situations: Clients building the header from a raw string instead of the account's 16-byte unidentified access key; double/truncated Base64 encoding; sending an empty header value that Base64-decodes to an empty array; old clients after a key-length change.
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
- Invalid combined unidentified sender access keys
- Missing credentials
- A group send endorsement token or unidentified access key…
- Multi-recipient messages must be addressed to ACI service…
- 400 Bad Request (invalid ProfileKeyCommitment base64)
AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09).
Data as JSON: /api/errors/8925b05eee279959.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/auth/Anonymous.java:20
* Copyright 2013-2020 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 java.util.Base64;
public class Anonymous {
private final byte[] unidentifiedSenderAccessKey;
public Anonymous(String header) {
try {
this.unidentifiedSenderAccessKey = Base64.getDecoder().decode(header);
if (unidentifiedSenderAccessKey.length != UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH) {
throw new WebApplicationException("access key length must be 16", Response.Status.UNAUTHORIZED);
}
} catch (IllegalArgumentException e) {
throw new WebApplicationException(e, Response.Status.UNAUTHORIZED);
}
}
public byte[] getAccessKey() {
return unidentifiedSenderAccessKey;
}
}
View on GitHub (pinned to 100ab61c82)