signalapp/Signal-Server · error · ServerRejectedException

return Response.status(508).build();

Error message

return Response.status(508).build();

What it means

The ServerRejectedExceptionMapper maps ServerRejectedException to HTTP 508 Loop Detected. It is returned when the registration service's fraud/abuse detection (or an upstream checker) flatly rejects the operation for this account/session — a deliberate server-side rejection rather than a rate limit or validation error. The body is empty.

Solutions

  1. Stop retrying — 508 is a deliberate rejection, and retries can worsen the flag
  2. Try from a different network/IP and a legitimate (non-VoIP) number if wrongly flagged
  3. Appeal via the service's support channels if the rejection is in error
  4. Review server-side abuse-check configuration if rejections are over-broad

Example fix

// before
while (!success) { requestVerification(number); } // retries into hard rejection
// after
if (response.code() == 508) {
  abortFlow("server rejected this number/session — do not retry");
}
Defensive patterns

Strategy: fallback

Validate before calling

// screen obviously flag-prone inputs before calling
if (phoneNumberUtil.getNumberType(number) == PhoneNumberType.VOIP && !allowVoip) {
  warnUser("this number type is commonly rejected");
}

Try / catch

if (response.code() == 508) {
  abortFlow("server rejected this operation; do not retry");
  offerSupportAppeal();
}

Prevention

When it happens

Trigger: Calling registration/verification endpoints (or anything that throws ServerRejectedException) where an anti-abuse backend signals a hard rejection of the request for the given number/session.

Common situations: Numbers or IPs on fraud blocklists; VoIP/virtual numbers flagged by abuse scoring; clients hammering verification flows until the fraud system hard-rejects them.

Related errors


AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09). Data as JSON: /api/errors/6f31b3677fb23070. Report an issue: GitHub.

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/mappers/ServerRejectedExceptionMapper.java:16

/*
 * Copyright 2021 Signal Messenger, LLC
 * SPDX-License-Identifier: AGPL-3.0-only
 */

package org.whispersystems.textsecuregcm.mappers;

import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import org.whispersystems.textsecuregcm.controllers.ServerRejectedException;

public class ServerRejectedExceptionMapper implements ExceptionMapper<ServerRejectedException> {

  @Override
  public Response toResponse(final ServerRejectedException exception) {
    return Response.status(508).build();
  }
}

View on GitHub (pinned to 100ab61c82)