{"record":{"id":"90266364577de1fe","repo":"signalapp/Signal-Server","slug":"failure-during-delivery","errorCode":null,"errorMessage":"failure during delivery","messagePattern":"failure during delivery","errorType":"http","errorClass":"InternalServerErrorException","httpStatus":500,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java","lineNumber":658,"sourceCode":"\n    try {\n      if (!resolvedRecipients.isEmpty()) {\n        messageSender.sendMultiRecipientMessage(multiRecipientMessage,\n            resolvedRecipients,\n            timestamp, isStory,\n            ephemeral,\n            urgent,\n            context.getHeaderString(HttpHeaders.USER_AGENT)).get();\n      }\n    } catch (final InterruptedException e) {\n      logger.error(\"interrupted while delivering multi-recipient messages\", e);\n      throw new InternalServerErrorException(\"interrupted during delivery\");\n    } catch (final CancellationException e) {\n      logger.error(\"cancelled while delivering multi-recipient messages\", e);\n      throw new InternalServerErrorException(\"delivery cancelled\");\n    } catch (final ExecutionException e) {\n      logger.error(\"partial failure while delivering multi-recipient messages\", e.getCause());\n      throw new InternalServerErrorException(\"failure during delivery\");\n    } catch (final MessageTooLargeException e) {\n      throw new WebApplicationException(Status.REQUEST_ENTITY_TOO_LARGE);\n    } catch (final MultiRecipientMismatchedDevicesException e) {\n      final List<AccountMismatchedDevices> accountMismatchedDevices =\n          e.getMismatchedDevicesByServiceIdentifier().entrySet().stream()\n              .filter(entry -> !entry.getValue().missingDeviceIds().isEmpty() || !entry.getValue().extraDeviceIds().isEmpty())\n              .map(entry -> new AccountMismatchedDevices(entry.getKey(),\n                  new MismatchedDevicesResponse(entry.getValue().missingDeviceIds(), entry.getValue().extraDeviceIds())))\n              .toList();\n\n      if (!accountMismatchedDevices.isEmpty()) {\n        throw new WebApplicationException(Response\n            .status(409)\n            .type(MediaType.APPLICATION_JSON_TYPE)\n            .entity(accountMismatchedDevices)\n            .build());\n      }\n","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java#L640-L676","documentation":"Thrown as HTTP 500 when at least one per-recipient delivery future in a multi-recipient send completes exceptionally (ExecutionException). The server logs the underlying cause and returns InternalServerErrorException 'failure during delivery'.","triggerScenarios":"One or more individual recipient message deliveries fail (storage/registration errors, downstream message-send exceptions) while the batch is being fanned out.","commonSituations":"A destination account in an inconsistent state; transient storage layer failure during a large story send.","solutions":["Retry the send; partial failures are often transient","Check server logs for the logged underlying cause to identify the failing recipient","If persistent, remove/re-resolve the problematic recipient's devices and resend"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await send(msg); } catch (e) { if (e.status === 500 && e.message === 'failure during delivery') await withBackoff(() => send(msg)); else throw e; }","preventionTips":["Retry transient partial failures","Verify recipient device registration state before sending","Resync device lists if failures persist for a specific contact"],"tags":["http-500","partial-failure","concurrency","signal-server"],"backgroundTag":"upstream-api-error","analyzedSha":"100ab61c82627582c867d19e1c0561ba2781e927","analyzedAt":"2026-09-09T13:29:47.883Z","contentChangedAt":"2026-09-09T13:29:47.883Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}