signalapp/Signal-Server · error · ClientErrorException
exceeded maximum uploadLength
Error message
exceeded maximum uploadLength
What it means
Before creating a message-backup upload descriptor, the controller validates the declared uploadLength against maxMessageBackupSize. If the declared size exceeds the limit, it throws ClientErrorException with HTTP 413 REQUEST_ENTITY_TOO_LARGE. The check uses the query parameter, not the actual body, so clients must declare their size honestly.
Solutions
- Reduce uploadLength to at most maxMessageBackupSize (obtain the current limit from the server's advertised max).
- Free space by removing old backups before re-uploading.
- Split the backup or upgrade the client to the latest version that respects current limits.
- If using uploadLength-less requests (default = max size), pass an explicit accurate length.
Example fix
// before
long length = backupBytes.length + extraAttachmentsBytes; // exceeds server max -> 413
// after
long length = backupBytes.length;
if (length > maxMessageBackupSize) {
throw new BackupTooLargeException(); // surface to user before calling server
} Defensive patterns
Strategy: validation
Validate before calling
long actual = backupBytes.length;
if (actual > maxMessageBackupSize) {
throw new BackupTooLargeException(actual, maxMessageBackupSize); // fail before calling server
} Try / catch
try {
createUploadDescriptor(uploadLength);
} catch (ClientErrorException e) {
if (e.getResponse().getStatus() == 413) {
handleBackupTooLarge();
} else throw e;
} Prevention
- Measure exact backup bytes instead of estimating or padding.
- Handle 413 by pruning old backups and retrying.
- Fetch the current server limit at runtime rather than hardcoding.
When it happens
Trigger: Calling the backup upload endpoint with ?uploadLength= greater than maxMessageBackupSize.
Common situations: Backups growing after a server-side limit reduction; clients rounding up or defaulting to an oversized length; uploading a full backup where only media quota differs; version skew between client assumption and server limit.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- Invalid length
- exceeded maximum uploadLength
- Blank header
- end of range must be after start of range
- timestamps must be day aligned
AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09).
Data as JSON: /api/errors/45d19aa159397f4b.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArchiveController.java:613
@HeaderParam(X_SIGNAL_ZK_AUTH_SIGNATURE) final BackupAuthCredentialPresentationSignature signature,
@Parameter(description = "The size of the message backup to upload in bytes")
@QueryParam("uploadLength") final Optional<Long> uploadLength)
throws BackupFailedZkAuthenticationException, BackupWrongCredentialTypeException, BackupPermissionException {
if (account.isPresent()) {
throw new BadRequestException("must not use authenticated connection for anonymous operations");
}
final AuthenticatedBackupUser backupUser =
backupManager.authenticateBackupUser(presentation.presentation, signature.signature, userAgent);
final boolean oversize = uploadLength
.map(length -> length > maxMessageBackupSize)
.orElse(false);
backupMetrics.updateMessageBackupSizeDistribution(backupUser, oversize, uploadLength);
if (oversize) {
throw new ClientErrorException("exceeded maximum uploadLength", Response.Status.REQUEST_ENTITY_TOO_LARGE);
}
final BackupUploadDescriptor uploadDescriptor =
backupManager.createMessageBackupUploadDescriptor(backupUser, uploadLength.orElse(maxMessageBackupSize));
return new UploadDescriptorResponse(
uploadDescriptor.cdn(),
uploadDescriptor.key(),
uploadDescriptor.headers(),
uploadDescriptor.signedUploadLocation());
}
@GET
@Path("/media/upload/form")
@Produces(MediaType.APPLICATION_JSON)
@Operation(
summary = "Fetch media attachment upload form",
description = """
Retrieve an upload form that can be used to perform a resumable upload of an attachment. After uploading, the
attachment can be copied into the backup at PUT /archives/media/.View on GitHub (pinned to 100ab61c82)