signalapp/Signal-Server · error · FieldValidationException

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

Error message

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

What it means

SizeFieldValidator.validateBytesValue throws FieldValidationException when a bytes proto field's byte length is outside the annotated [min, max] size range. The message shows the actual byte size and allowed bounds.

Solutions

  1. Check fieldValue.toByteArray().length against the documented min/max before sending
  2. Trim or chunk oversized payloads; regenerate truncated ones
  3. If the size constraint is wrong for your use case, adjust the proto size annotation server-side

Example fix

// before
builder.setProfileKey(profileKeyBytes); // may be any length
// after
if (profileKeyBytes.length != 32) {
  throw new IllegalArgumentException("profile key must be 32 bytes");
}
builder.setProfileKey(profileKeyBytes);
Defensive patterns

Strategy: validation

Validate before calling

int len = bytes == null ? 0 : bytes.length; if (len < MIN || len > MAX) throw new IllegalArgumentException("byte size " + len + " outside [" + MIN + ", " + MAX + "]");

Try / catch

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

Prevention

When it happens

Trigger: Sending a Signal gRPC request with a bytes field (e.g. encrypted payload, profile key, sender certificate) that is too short or longer than the annotated max.

Common situations: Truncated base64 decoding; oversized attachments/metadata payloads; sending empty byte strings where a minimum length is required; protocol version changes altering expected payload sizes.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/SizeFieldValidator.java:34

  public SizeFieldValidator() {
    super("size", Set.of(
        Descriptors.FieldDescriptor.Type.STRING,
        Descriptors.FieldDescriptor.Type.BYTES
    ), MissingOptionalAction.VALIDATE_DEFAULT_VALUE, true);
  }

  @Override
  protected Range resolveExtensionValue(final Object extensionValue) throws FieldValidationException {
    final SizeConstraint sizeConstraint = (SizeConstraint) extensionValue;
    final int min = sizeConstraint.hasMin() ? sizeConstraint.getMin() : 0;
    final int max = sizeConstraint.hasMax() ? sizeConstraint.getMax() : Integer.MAX_VALUE;
    return new Range(min, max);
  }

  @Override
  protected void validateBytesValue(final Range range, final ByteString fieldValue) throws FieldValidationException {
    if (fieldValue.size() < range.min() || fieldValue.size() > range.max()) {
      throw new FieldValidationException("field value is [%d] but expected to be within the [%d, %d] range".formatted(
          fieldValue.size(), range.min(), range.max()));
    }
  }

  @Override
  protected void validateStringValue(final Range range, final String fieldValue) throws FieldValidationException {
    if (fieldValue.length() < range.min() || fieldValue.length() > range.max()) {
      throw new FieldValidationException("field value is [%d] but expected to be within the [%d, %d] range".formatted(
          fieldValue.length(), range.min(), range.max()));
    }
  }

  @Override
  protected void validateRepeatedField(final Range range, final Descriptors.FieldDescriptor fd, final List<?> repeated) throws FieldValidationException {
    final int size = repeated.size();
    if (size < range.min() || size > range.max()) {
      throw new FieldValidationException("field value is [%d] but expected to be within the [%d, %d] range".formatted(
          size, range.min(), range.max()));

View on GitHub (pinned to 100ab61c82)