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
- Upgrade the client to a version that normalizes numbers to current E.164 format
- Normalize/reformat the phone number (proper +country code, no spaces/dashes) before sending
- Check the per-region metrics counter (regionCode tag) to identify which regions' clients need updating
- 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
- Always normalize numbers to E.164 before API calls
- Keep the client's libphonenumber/regional formatting current
- Watch the per-region 499 metrics to find outdated client populations
- Scrub cached contacts of legacy formats
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
- value is not in E164 format
- Empty body not allowed
- 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/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)