signalapp/Signal-Server · error · BadRequestException
Recipient list is empty
Error message
Recipient list is empty
What it means
Thrown by sendMultiRecipientMessage when the recipient list resolved from the sealed-sender multi-recipient payload is empty. A multi-recipient message must name at least one recipient; a request whose decoded payload contains zero recipient entries fails this validation guard and is rejected with a 400-style client error.
Solutions
- Check the recipient list client-side and skip the send (or surface an error) when it is empty.
- Rebuild the multi-recipient message ensuring all intended recipients' entries are serialized.
- Verify the distribution list/group actually has members at send time.
Example fix
// before
sendMultiRecipient(message); // recipients may be empty
// after
if (recipients.isEmpty()) { return; /* nothing to send */ }
sendMultiRecipient(message); Defensive patterns
Strategy: validation
Validate before calling
if (!recipients || recipients.length === 0) return; // nothing to send, skip the API call
Type guard
function hasRecipients(recipients) { return Array.isArray(recipients) && recipients.length > 0; } Try / catch
try { await sendMultiRecipient(msg); } catch (e) { if (e.status === 400 && /Recipient list is empty/.test(e.body)) { logSkipAndAbortSend(); } } Prevention
- Check group/distribution list membership before building the message
- Handle the case where filtering removes all recipients
- Test the empty-group edge case in client code
When it happens
Trigger: POST to the multi-recipient endpoint with a SealedSenderMultiRecipientMessage whose getRecipients() map is empty — i.e. the serialized payload contains no recipient entries.
Common situations: Client built the message from an empty distribution list or group with all members removed; recipient filtering (e.g. skipping unsent-to users) eliminated everyone; serialization bug dropping recipients.
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
- Invalid length
- Invalid create call link credential request
- Illegal timestamp
- Multi-recipient message contains duplicate recipient
- 400 Bad Request (UNSUPPORTED_LEVEL)
AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09).
Data as JSON: /api/errors/11c4ce8e5238c23f.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java:496
@Parameter(description="The sender's timestamp for the envelope")
@QueryParam("ts") long timestamp,
@Parameter(description="If true, this message should cause push notifications to be sent to recipients")
@QueryParam("urgent") @DefaultValue("true") final boolean isUrgent,
@Parameter(description="If true, the message is a story; access tokens are not checked and sending to nonexistent recipients is permitted")
@QueryParam("story") boolean isStory,
@Parameter(description="The sealed-sender multi-recipient message payload as serialized by libsignal")
@NotNull SealedSenderMultiRecipientMessage multiRecipientMessage,
@Context ContainerRequestContext context) {
if (timestamp < 0 || timestamp > MAX_TIMESTAMP) {
throw new BadRequestException("Illegal timestamp");
}
if (multiRecipientMessage.getRecipients().isEmpty()) {
throw new BadRequestException("Recipient list is empty");
}
final Timer.Sample sample = Timer.start();
try {
final SendMultiRecipientMessageResponse sendMultiRecipientMessageResponse;
if (isStory) {
if (groupSendToken != null) {
// Stories require no authentication. We fail requests that provide a groupSendToken, but for historical
// reasons we allow requests to set a combined access key, even though we ignore it
throw new BadRequestException("Group send token not allowed when sending stories");
}
sendMultiRecipientMessageResponse =
sendMultiRecipientStoryMessage(multiRecipientMessage, timestamp, online, isUrgent, context);
} else {
sendMultiRecipientMessageResponse =View on GitHub (pinned to 100ab61c82)