signalapp/Signal-Server · error · FieldValidationException

field value is expected to be within the

Error message

field value is expected to be within the [%d, %d] range

What it means

RangeFieldValidator.validateIntegerNumber throws FieldValidationException when a negative value is supplied for a proto field whose type is an unsigned integer type (uint32/uint64), since negative numbers can never be in an unsigned range. The message shows the field's configured [min, max] range.

Solutions

  1. Clamp or reject negative values before setting unsigned proto fields
  2. Use sentinel values >= 0 (or optional fields) instead of -1 for 'unknown'
  3. Verify the field type in the proto; switch to a signed int type if negatives are legitimate

Example fix

// before
builder.setDeviceId(deviceId); // deviceId may be -1
// after
if (deviceId < 0) {
  throw new IllegalArgumentException("deviceId must be non-negative");
}
builder.setDeviceId(deviceId);
Defensive patterns

Strategy: validation

Validate before calling

if (value < 0) throw new IllegalArgumentException("unsigned proto field cannot be negative");

Type guard

boolean isValidUnsigned(long v) { return v >= 0; }

Try / catch

try { stub.call(request); } catch (StatusRuntimeException e) { if (e.getStatus().getCode() == Status.Code.INVALID_ARGUMENT && e.getMessage().contains("range")) { /* handle unsigned violation */ } }

Prevention

When it happens

Trigger: Passing a negative long into a proto field declared uint32/uint64 and covered by a range annotation in a Signal gRPC request; e.g. sending -1 for a device ID or counter.

Common situations: Java int arithmetic producing negatives (overflow, subtraction) before conversion; clients using signed types in their own language and casting; sentinel values like -1 used for 'unknown'.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/RangeFieldValidator.java:50

        Descriptors.FieldDescriptor.Type.SINT64
    ), MissingOptionalAction.SUCCEED, false);
  }

  @Override
  protected Range resolveExtensionValue(final Object extensionValue) {
    final ValueRangeConstraint rangeConstraint = (ValueRangeConstraint) extensionValue;
    final long min = rangeConstraint.hasMin() ? rangeConstraint.getMin() : Long.MIN_VALUE;
    final long max = rangeConstraint.hasMax() ? rangeConstraint.getMax() : Long.MAX_VALUE;
    return new Range(min, max);
  }

  @Override
  protected void validateIntegerNumber(
      final Range range,
      final long fieldValue,
      final Descriptors.FieldDescriptor.Type type) throws FieldValidationException {
    if (fieldValue < 0 && UNSIGNED_TYPES.contains(type)) {
      throw new FieldValidationException("field value is expected to be within the [%d, %d] range".formatted(
          range.min(), range.max()));
    }
    if (fieldValue < range.min() || fieldValue > range.max()) {
      throw new FieldValidationException("field value is [%d] but expected to be within the [%d, %d] range".formatted(
          fieldValue, range.min(), range.max()));
    }
  }
}

View on GitHub (pinned to 100ab61c82)