signalapp/Signal-Server · error · JsonParseException
Could not interpret identity key bytes as an EC public key
Error message
Could not interpret identity key bytes as an EC public key
What it means
Thrown by IdentityKeyAdapter during Jackson deserialization when a JSON field holds bytes that cannot be interpreted as an EC public key. The adapter wraps libsignal's InvalidKeyException in a JsonParseException so the failure surfaces as a JSON binding error. It indicates the supplied identity key material is malformed, the wrong length, or not a valid EC point.
Solutions
- Verify the source of the identity key bytes and regenerate/obtain them from a valid identity key pair.
- Check that the sender is encoding the key the same way the adapter expects (base64 string decoded to raw EC public key bytes).
- Confirm client and server library versions agree on identity key format (no protocol version mismatch).
- Inspect the raw bytes: a valid EC public key for this format is the compressed 33-byte or expected fixed-length encoding; fix truncation if length is wrong.
- Wrap deserialization in a try-catch for JsonParseException and reject the request with a 400 rather than a 500.
Example fix
// before (invalid payload)
{"identityKey": "not-a-real-key"}
// after (valid base64-encoded EC public key bytes)
{"identityKey": "BQBIQ6b3bBsVhS9pJwJciT2C0rOd7VCLb5Bt9eHwzO0R"} Defensive patterns
Strategy: validation
Validate before calling
// before deserializing
byte[] keyBytes = Base64.getDecoder().decode(rawKey);
if (keyBytes.length != 33) {
throw new IllegalArgumentException("Identity key must be 33-byte compressed EC point, got " + keyBytes.length);
}
if (keyBytes[0] != 0x05) {
throw new IllegalArgumentException("Identity key must start with compressed-point prefix 0x05");
} Try / catch
try {
IdentityKey key = objectMapper.treeToValue(node, AccountAttributes.class);
} catch (JsonParseException e) {
if (e.getCause() instanceof InvalidKeyException) {
throw new BadRequestException("identity key is not a valid EC public key");
}
throw e;
} Prevention
- Serialize keys with the same IdentityKey.serialize()/base64 path on both ends
- Assert key byte length (33 for compressed EC points) in client tests
- Keep signal-protocol library versions aligned between client and server
- Validate identity keys at API boundary and return 400, never 500
When it happens
Trigger: Deserializing a JSON payload whose identity key field is not valid base64-decoded EC public key bytes, e.g. truncated key material, an ed25519 key instead of an EC (x25519/derived EC) key, or corrupted bytes from a bad client payload.
Common situations: Clients sending identity keys in the wrong encoding after a protocol/version change; test fixtures with fake key bytes; payloads edited or truncated in transit; mixing identity key types (ACI vs PNI) from different account versions.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Could not interpret bytes as a ZK credential public key
- Could not parse key as a base64-encoded value
- return Response.status(422).build();
- exceeded maximum uploadLength
- Invalid length
AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09).
Data as JSON: /api/errors/c0778b815625de18.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/util/IdentityKeyAdapter.java:52
@Override
public IdentityKey deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
final byte[] identityKeyBytes;
try {
identityKeyBytes = Base64.getDecoder().decode(parser.getValueAsString());
} catch (final IllegalArgumentException e) {
throw new JsonParseException(parser, "Could not parse identity key as a base64-encoded value", e);
}
if (identityKeyBytes.length == 0) {
return null;
}
try {
return new IdentityKey(identityKeyBytes);
} catch (final InvalidKeyException e) {
throw new JsonParseException(parser, "Could not interpret identity key bytes as an EC public key", e);
}
}
}
}
View on GitHub (pinned to 100ab61c82)