signalapp/Signal-Server · error · FieldValidationException
byte array length is
Error message
byte array length is [%d] but expected to be one of %s
What it means
ExactlySizeFieldValidator.validateBytesValue checks that a proto bytes field's ByteString is exactly one of a configured set of permitted sizes. If fieldValue.size() is not in permittedSizes, it throws FieldValidationException with a formatted message including the actual and permitted sizes.
Solutions
- Check the required length(s) from the error's permitted sizes list and regenerate the value at the correct length
- Verify client-side byte arrays are exactly the expected size before encoding into the proto
- Ensure the value wasn't truncated/extended by an intermediate encode/decode step
- Align client library version with the server's expected field sizes
Example fix
// before byte[] key = new byte[16]; // after byte[] key = new byte[32]; // matches permittedSizes [32]
Defensive patterns
Strategy: validation
Validate before calling
if (!permittedSizes.contains(bytes.length)) {
throw new IllegalArgumentException("expected bytes length in " + permittedSizes + ", got " + bytes.length);
} Try / catch
try {
grpcStub.call(request);
} catch (StatusRuntimeException e) {
if (e.getStatus().getCode() == Code.INVALID_ARGUMENT && e.getStatus().getDescription().contains("byte array length")) {
// regenerate the bytes at the permitted size
}
} Prevention
- Check key/byte-array lengths right after generation
- Consult the proto validator annotation to learn required sizes
- Avoid encode/decode round-trips that change array length
When it happens
Trigger: gRPC requests with bytes fields (e.g. profile keys, storage keys, receipt data) whose decoded byte length does not match the required size(s) enforced via proto validator annotations.
Common situations: Sending keys of wrong length (e.g. 16 vs 32 bytes) after generating them with a different algorithm; truncating or padding data in client code; version mismatches where the server tightened required sizes.
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
- string length is [ ] but expected to be one of
- list size is [ ] but expected to be one of
- byte array expected to be non-empty
- field value is [ ] but expected to be within the [ , ] range
- value is not valid base64 url
AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09).
Data as JSON: /api/errors/6bf7256fced04c69.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/ExactlySizeFieldValidator.java:35
Descriptors.FieldDescriptor.Type.STRING,
Descriptors.FieldDescriptor.Type.BYTES
), MissingOptionalAction.VALIDATE_DEFAULT_VALUE, true);
}
@Override
protected Set<Integer> resolveExtensionValue(final Object extensionValue) {
//noinspection unchecked
return Set.copyOf((List<Integer>) extensionValue);
}
@Override
protected void validateBytesValue(
final Set<Integer> permittedSizes,
final ByteString fieldValue) throws FieldValidationException {
if (permittedSizes.contains(fieldValue.size())) {
return;
}
throw new FieldValidationException("byte array length is [%d] but expected to be one of %s".formatted(fieldValue.size(), permittedSizes));
}
@Override
protected void validateStringValue(
final Set<Integer> permittedSizes,
final String fieldValue) throws FieldValidationException {
if (permittedSizes.contains(fieldValue.length())) {
return;
}
throw new FieldValidationException("string length is [%d] but expected to be one of %s".formatted(fieldValue.length(), permittedSizes));
}
@Override
protected void validateRepeatedField(
final Set<Integer> permittedSizes,
final Descriptors.FieldDescriptor fd,
final List<?> repeated) throws FieldValidationException {
if (permittedSizes.contains(repeated.size())) {View on GitHub (pinned to 100ab61c82)