signalapp/Signal-Server · error · JsonParseException

Could not interpret bytes as a BackupAuth object

Error message

Could not interpret bytes as a BackupAuth object

What it means

Thrown by BackupAuthCredentialAdapter's GenericDeserializer when Base64 decoding succeeds but the abstract deserialize(bytes) call raises InvalidInputException because the bytes are not a valid BackupAuth object (wrong structure, version, or length). The failure is counted via INVALID_BYTES_COUNTER and rethrown as a JsonParseException, failing deserialization of the field.

Solutions

  1. Verify the Base64-decoded bytes form a valid BackupAuth credential object in the expected format
  2. Confirm the client serializes the BackupAuth object (e.g. via serialize()) before Base64-encoding it
  3. Check for corrupted or version-mismatched credential bytes in the request
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at service/src/main/java/org/whispersystems/textsecuregcm/util/BackupAuthCredentialAdapter.java:50 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09). Data as JSON: /api/errors/9c59db18e9e82824. Report an issue: GitHub.

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/util/BackupAuthCredentialAdapter.java:50

  abstract static class GenericDeserializer<T> extends JsonDeserializer<T> {

    abstract T deserialize(final byte[] bytes) throws InvalidInputException;

    @Override
    public T deserialize(final JsonParser parser, final DeserializationContext deserializationContext)
        throws IOException {
      final byte[] bytes;
      try {
        bytes = Base64.getDecoder().decode(parser.getValueAsString());
      } catch (final IllegalArgumentException e) {
        INVALID_BASE64_COUNTER.increment();
        throw new JsonParseException(parser, "Could not parse string as a base64-encoded value", e);
      }
      try {
        return deserialize(bytes);
      } catch (InvalidInputException e) {
        INVALID_BYTES_COUNTER.increment();
        throw new JsonParseException(parser, "Could not interpret bytes as a BackupAuth object");
      }
    }
  }

  static class GenericSerializer<T extends ByteArray> extends JsonSerializer<T> {

    @Override
    public void serialize(final T t, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
        throws IOException {
      jsonGenerator.writeString(Base64.getEncoder().encodeToString(t.serialize()));
    }
  }

  public static class CredentialRequestSerializer extends GenericSerializer<BackupAuthCredentialRequest> {}
  public static class CredentialRequestDeserializer extends GenericDeserializer<BackupAuthCredentialRequest> {
    @Override
    BackupAuthCredentialRequest deserialize(final byte[] bytes) throws InvalidInputException {
      return new BackupAuthCredentialRequest(bytes);

View on GitHub (pinned to 100ab61c82)