signalapp/Signal-Server · warning · ObsoletePhoneNumberFormatException

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

Error message

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

What it means

The ObsoletePhoneNumberFormatExceptionMapper turns an ObsoletePhoneNumberFormatException into HTTP 499 (client-closed-request, Signal's reuse) and increments a per-region error counter. The exception indicates the request supplied a phone number in an obsolete/legacy format that this server no longer accepts (e.g. old national-format or deprecated e164 handling for certain regions).

Solutions

  1. Upgrade the client to a version that normalizes numbers to current E.164 format
  2. Normalize/reformat the phone number (proper +country code, no spaces/dashes) before sending
  3. Check the per-region metrics counter (regionCode tag) to identify which regions' clients need updating
  4. If a legitimate regional format is rejected, update the server's number-parsing library/configuration

Example fix

// before
String number = "(415) 555-2671";
api.register(number);
// after
String number = PhoneNumberUtil.getInstance().format(raw, PhoneNumberFormat.E164); // +14155552671
api.register(number);
Defensive patterns

Strategy: validation

Validate before calling

// normalize to E.164 before any API call
String e164 = PhoneNumberUtil.getInstance().format(
    PhoneNumberUtil.getInstance().parse(rawNumber, defaultRegion), PhoneNumberFormat.E164);
if (!e164.startsWith("+")) throw new IllegalArgumentException("not E.164: " + rawNumber);

Type guard

boolean isModernE164(String n) {
  return n != null && n.matches("\\+[1-9]\\d{7,14}");
}

Try / catch

if (response.code() == 499) {
  log.warn("obsolete phone format for region; upgrade client/normalize number");
  normalizeAndResend();
}

Prevention

When it happens

Trigger: Any endpoint validating phone numbers receiving a number that parses to an obsolete format for its region code — legacy formatting the server has deliberately dropped support for.

Common situations: Old clients (pre-format-migration) still sending numbers without strict E.164 normalization; numbers from regions whose formatting rules changed; cached contact lists containing legacy-formatted numbers.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


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

Appendix: source

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

package org.whispersystems.textsecuregcm.mappers;

import io.micrometer.core.instrument.Metrics;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
import org.whispersystems.textsecuregcm.util.ObsoletePhoneNumberFormatException;

public class ObsoletePhoneNumberFormatExceptionMapper implements ExceptionMapper<ObsoletePhoneNumberFormatException> {

  private static final String COUNTER_NAME = MetricsUtil.name(ObsoletePhoneNumberFormatExceptionMapper.class, "errors");

  @Override
  public Response toResponse(final ObsoletePhoneNumberFormatException exception) {
    Metrics.counter(COUNTER_NAME, "regionCode", exception.getRegionCode()).increment();
    return Response.status(499).build();
  }
}

View on GitHub (pinned to 100ab61c82)