signalapp/Signal-Server · error · FieldValidationException
byte array expected to be non-empty
Error message
byte array expected to be non-empty
What it means
NonEmptyFieldValidator.validateBytesValue rejects empty ByteString fields. If the bytes field is empty, it throws FieldValidationException('byte array expected to be non-empty'), enforcing that required binary fields carry data.
Solutions
- Ensure the byte array is generated/loaded (non-zero length) before placing it in the request
- Check client-side: if the field is genuinely optional, don't set the field at all rather than setting empty bytes
- Verify the key-generation step didn't fail silently and return an empty array
- Log/inspect the value on the client to confirm non-empty content before sending
Example fix
// before
byte[] backupKey = new byte[0];
request.setBackupKey(ByteString.copyFrom(backupKey));
// after
if (backupKey.length > 0) {
request.setBackupKey(ByteString.copyFrom(backupKey));
} Defensive patterns
Strategy: validation
Validate before calling
if (bytes == null || bytes.length == 0) {
throw new IllegalArgumentException("required byte field must be non-empty");
} Type guard
static boolean isNonEmpty(ByteString b) { return b != null && !b.isEmpty(); } Try / catch
try {
grpcStub.call(request);
} catch (StatusRuntimeException e) {
if (e.getStatus().getCode() == Code.INVALID_ARGUMENT && e.getStatus().getDescription().contains("non-empty")) {
// generate/load the missing key material and retry
}
} Prevention
- Only set bytes fields when real data exists; omit optional fields instead of sending empty
- Fail fast client-side when key generation returns zero bytes
- Check preconditions of any async operation that produces the byte field before sending the request
When it happens
Trigger: gRPC requests where a bytes field (e.g. profile key, backup key, storage manifest) is present but zero-length — typically because the client passed a new byte[0] or an unset/empty value.
Common situations: Client code generating keys before they are ready (no key material available yet); failing to check a byte array before encoding; proto fields defaulting to empty bytes when not explicitly set.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- byte array length is
- field value is [ ] but expected to be within the [ , ] range
- 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/6f86a78856890b96.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/NonEmptyFieldValidator.java:35
super("nonEmpty", Set.of(
Descriptors.FieldDescriptor.Type.STRING,
Descriptors.FieldDescriptor.Type.BYTES
), MissingOptionalAction.FAIL, true);
}
@Override
protected Boolean resolveExtensionValue(final Object extensionValue) throws FieldValidationException {
return requireFlagExtension(extensionValue);
}
@Override
protected void validateBytesValue(
final Boolean extensionValue,
final ByteString fieldValue) throws FieldValidationException {
if (!fieldValue.isEmpty()) {
return;
}
throw new FieldValidationException("byte array expected to be non-empty");
}
@Override
protected void validateStringValue(
final Boolean extensionValue,
final String fieldValue) throws FieldValidationException {
if (StringUtils.isNotEmpty(fieldValue)) {
return;
}
throw new FieldValidationException("string expected to be non-empty");
}
@Override
protected void validateRepeatedField(
final Boolean extensionValue,
final Descriptors.FieldDescriptor fd,
final List<?> repeated) throws FieldValidationException {
if (repeated.size() > 0) {View on GitHub (pinned to 100ab61c82)