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

  1. Pass an identifier whose identity type matches the annotation (e.g. AciServiceIdentifier for ACI fields)
  2. Parse identifiers with the correct typed valueOf (AciServiceIdentifier.valueOf vs PniServiceIdentifier.valueOf)
  3. 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

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


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)