{"record":{"id":"c0778b815625de18","repo":"signalapp/Signal-Server","slug":"could-not-interpret-identity-key-bytes-as-an-ec-pu","errorCode":null,"errorMessage":"Could not interpret identity key bytes as an EC public key","messagePattern":"Could not interpret identity key bytes as an EC public key","errorType":"validation","errorClass":"JsonParseException","httpStatus":400,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/util/IdentityKeyAdapter.java","lineNumber":52,"sourceCode":"\n    @Override\n    public IdentityKey deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {\n      final byte[] identityKeyBytes;\n\n      try {\n        identityKeyBytes = Base64.getDecoder().decode(parser.getValueAsString());\n      } catch (final IllegalArgumentException e) {\n        throw new JsonParseException(parser, \"Could not parse identity key as a base64-encoded value\", e);\n      }\n\n      if (identityKeyBytes.length == 0) {\n        return null;\n      }\n\n      try {\n        return new IdentityKey(identityKeyBytes);\n      } catch (final InvalidKeyException e) {\n        throw new JsonParseException(parser, \"Could not interpret identity key bytes as an EC public key\", e);\n      }\n    }\n  }\n}\n","sourceCodeStart":34,"sourceCodeEnd":57,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/util/IdentityKeyAdapter.java#L34-L57","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (invalid payload)\n{\"identityKey\": \"not-a-real-key\"}\n// after (valid base64-encoded EC public key bytes)\n{\"identityKey\": \"BQBIQ6b3bBsVhS9pJwJciT2C0rOd7VCLb5Bt9eHwzO0R\"}","handlingStrategy":"validation","validationCode":"// before deserializing\nbyte[] keyBytes = Base64.getDecoder().decode(rawKey);\nif (keyBytes.length != 33) {\n    throw new IllegalArgumentException(\"Identity key must be 33-byte compressed EC point, got \" + keyBytes.length);\n}\nif (keyBytes[0] != 0x05) {\n    throw new IllegalArgumentException(\"Identity key must start with compressed-point prefix 0x05\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    IdentityKey key = objectMapper.treeToValue(node, AccountAttributes.class);\n} catch (JsonParseException e) {\n    if (e.getCause() instanceof InvalidKeyException) {\n        throw new BadRequestException(\"identity key is not a valid EC public key\");\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["json","deserialization","identity-key","signal"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"100ab61c82627582c867d19e1c0561ba2781e927","analyzedAt":"2026-09-09T13:29:47.883Z","contentChangedAt":"2026-09-09T13:29:47.883Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}