signalapp/Signal-Server · error · FieldValidationException
string length is [ ] but expected to be one of
Error message
string length is [%d] but expected to be one of %s
What it means
ExactlySizeFieldValidator.validateStringValue checks that a proto string field's length is one of the permitted sizes. If not, it throws FieldValidationException with the actual length and allowed sizes in the message.
Solutions
- Truncate or otherwise conform the string to one of the lengths listed in the error message
- Check whether you should be sending base64url rather than hex (or vice versa) — different lengths for the same data
- Validate string length client-side before building the request
- Empty string may be the issue: confirm the value is present
Example fix
// before String deviceId = Hex.toStringCondensed(uuidBytes); // 64 chars // after String deviceId = uuid.toString(); // 36 chars, matches permitted size
Defensive patterns
Strategy: validation
Validate before calling
if (!permittedSizes.contains(value.length())) {
throw new IllegalArgumentException("expected string length in " + permittedSizes + ", got " + value.length());
} Try / catch
try {
grpcStub.call(request);
} catch (StatusRuntimeException e) {
if (e.getStatus().getCode() == Code.INVALID_ARGUMENT && e.getStatus().getDescription().contains("string length")) {
// adjust encoding (hex vs base64url) or truncate to permitted size
}
} Prevention
- Match encoding scheme to server expectation (hex=2N chars, base64=~4/3N chars)
- Validate lengths locally before building requests
- Truncate/pad only where semantics allow it
When it happens
Trigger: gRPC requests with string fields (e.g. device names, tokens, encoded identifiers) annotated with exact-size validation whose character count isn't in permittedSizes — e.g. deviceName longer than 50 chars, or a token of unexpected length.
Common situations: Client sending empty strings where a fixed-length token is required; localized names/IDs that exceed the configured length; encoders producing variable-length output (hex vs base64) for the same underlying data.
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
- byte array length is
- list size is [ ] but expected to be one of
- value is not valid base64 url
- value is not in E164 format
- enum field must be specified
AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09).
Data as JSON: /api/errors/becd4555a3f8c49e.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/ExactlySizeFieldValidator.java:45
@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())) {
return;
}
throw new FieldValidationException("list size is [%d] but expected to be one of %s".formatted(repeated.size(), permittedSizes));
}
}
View on GitHub (pinned to 100ab61c82)