signalapp/Signal-Server · error · SecureValueRecoveryException
Failed to delete backup
Error message
Failed to delete backup
What it means
SecureValueRecoveryClient.removeData DELETEs a user's SVR backup and expects a success status. On failure, it throws SecureValueRecoveryException('Failed to delete backup', status) after logging; only explicitly allowed error codes are swallowed and treated as success. Callers (account deletion flows) get this exception whenever the SVR service rejects the deletion.
Solutions
- Check the logged status code ('Failed to delete svr entry ... with status <code>') to identify the SVR rejection reason.
- If the status is benign (e.g. 404 for an already-deleted backup), add it to allowedErrors in removeData.
- Verify connectivity/credentials to the Secure Value Recovery service.
- Retry the deletion if the failure was transient (5xx); account deletion jobs typically retry.
- Catch SecureValueRecoveryException in the deletion flow and proceed/degrade appropriately per product policy.
Example fix
// before
throw new SecureValueRecoveryException("Failed to delete backup", String.valueOf(response.statusCode()));
// after: treat 404 as already-deleted
Set<Integer> allowedErrors = Set.of(401, 403, 404);
if (allowedErrors.contains(response.statusCode())) {
return null;
}
throw new SecureValueRecoveryException("Failed to delete backup", String.valueOf(response.statusCode())); Defensive patterns
Strategy: try-catch
Try / catch
try {
svrClient.removeData(accountIdentifier);
} catch (SecureValueRecoveryException e) {
logger.warn("SVR delete failed with status {} — continuing account deletion", e.getStatus());
// decide per policy: retry later, or proceed since local deletion is authoritative
} Prevention
- Keep allowedErrors current as SVR service statuses evolve (e.g. treat 404/410 as success).
- Make account-deletion jobs idempotent and retrying so transient SVR failures self-heal.
- Alert on sustained 'Failed to delete svr entry' warnings indicating SVR outages or auth misconfig.
When it happens
Trigger: Calling removeData (e.g. during account deletion) when the SVR service returns a non-success HTTP status not in allowedErrors — service outage, unknown account/backup id, or authentication failure against the SVR peer.
Common situations: SVR backend down or degraded during bulk account deletions, mismatched credentials/config for the remote SVR service, or new status codes (e.g. 410 Gone, 404) not yet added to allowedErrors.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Only primary device can set backup-id
- Must set at least one of message/media credential requests
- receipt credential presentation verification failed
- Invalid sourceObject size
- unknown cdn
AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09).
Data as JSON: /api/errors/56415642b7a90721.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/securevaluerecovery/SecureValueRecoveryClient.java:93
final HttpRequest request = HttpRequest.newBuilder()
.uri(deleteUri)
.DELETE()
.header(HttpHeaders.AUTHORIZATION, basicAuthHeader(credentials))
.build();
return httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenApply(response -> {
if (HttpUtils.isSuccessfulResponse(response.statusCode())) {
return null;
}
final List<Integer> allowedErrors = allowedDeletionErrorStatusCodes.get();
if (allowedErrors.contains(response.statusCode())) {
logger.warn("Ignoring failure to delete svr entry for identifier {} with status {}",
userIdentifier, response.statusCode());
return null;
}
logger.warn("Failed to delete svr entry for identifier {} with status {}", userIdentifier, response.statusCode());
throw new SecureValueRecoveryException("Failed to delete backup", String.valueOf(response.statusCode()));
});
}
}
View on GitHub (pinned to 100ab61c82)