signalapp/Signal-Server · error · FieldValidationException
identity type must be
Error message
identity type must be
What it means
ServiceIdentifierIdentityTypeValidator.validateMessageValue throws FieldValidationException when a ServiceIdentifier message field carries an identity type (ACI/PNI) different from the one required by the annotation. The message ends with the expected identity type name from the proto enum descriptor.
Solutions
- Pass an identifier whose identity type matches the annotation (e.g. AciServiceIdentifier for ACI fields)
- Parse identifiers with the correct typed valueOf (AciServiceIdentifier.valueOf vs PniServiceIdentifier.valueOf)
- Check the prefix ("ACI:" vs "PNI:") of the identifier string before sending
Example fix
// before ServiceIdentifier id = PniServiceIdentifier.valueOf(pniString); // field requires ACI // after ServiceIdentifier id = AciServiceIdentifier.valueOf(aciString);
Defensive patterns
Strategy: type-guard
Validate before calling
if (id instanceof PniServiceIdentifier && fieldRequiresAci) throw new IllegalArgumentException("expected ACI identifier"); Type guard
boolean isAci(ServiceIdentifier id) { return id instanceof AciServiceIdentifier; } Try / catch
try { stub.call(request); } catch (StatusRuntimeException e) { if (e.getStatus().getCode() == Status.Code.INVALID_ARGUMENT && e.getMessage().startsWith("identity type must be")) { /* handle wrong identity type */ } } Prevention
- Use AciServiceIdentifier/PniServiceIdentifier types instead of raw strings
- Check the identifier's string prefix (ACI:/PNI:) before sending
- Keep ACI and PNI values in separate, named fields/variables
When it happens
Trigger: Passing a PNI service identifier where an ACI is required (or vice versa) in a Signal gRPC request field annotated with a specific IdentityType, e.g. sending a PNI:... identifier to an endpoint expecting ACI.
Common situations: Mixing up ACI and PNI UUIDs stored client-side; using a generic ServiceId where a typed one is required; refactors that swap identifier fields.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- byte array expected to be non-empty
- byte array length is
- enum field must be specified
- field value is [ ] but expected to be within the [ , ] range
- field value is [ ] but expected to be within the [ , ] range
AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09).
Data as JSON: /api/errors/6a7d38ba87463391.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/ServiceIdentifierIdentityTypeValidator.java:47
default -> throw new IllegalArgumentException("unsupported value: " + d.getName());
};
}
}
throw new IllegalArgumentException("value must be org.signal.chat.require.IdentityType");
}
@Override
protected void validateMessageValue(final IdentityType extensionValue, final Message msg) throws FieldValidationException {
if (msg == null) {
return;
}
if (msg instanceof ServiceIdentifier i) {
if (i.getIdentityType() == extensionValue) {
return;
}
throw new FieldValidationException("identity type must be " + extensionValue.getValueDescriptor().getName());
}
throw new IllegalArgumentException("field must be " + ServiceIdentifier.class.getName());
}
}
View on GitHub (pinned to 100ab61c82)