diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java
index 9526410dcf273b9db9b1427df09d01447d39bf33..c53217989e97971e6938f4d7bcdb0caefe3cbdca 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java
@@ -90,7 +90,14 @@ public class OlmGroupSessionTest {
     @Test
     public void test02GetOutboundGroupSessionIdentifier() {
         // test session ID
-        mAliceSessionIdentifier = mAliceOutboundGroupSession.sessionIdentifier();
+        mAliceSessionIdentifier = null;
+
+        try {
+            mAliceSessionIdentifier = mAliceOutboundGroupSession.sessionIdentifier();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
+
         assertNotNull(mAliceSessionIdentifier);
         assertTrue(mAliceSessionIdentifier.length() > 0);
     }
@@ -98,7 +105,13 @@ public class OlmGroupSessionTest {
     @Test
     public void test03GetOutboundGroupSessionKey() {
         // test session Key
-        mAliceOutboundSessionKey = mAliceOutboundGroupSession.sessionKey();
+        mAliceOutboundSessionKey = null;
+
+        try {
+            mAliceOutboundSessionKey = mAliceOutboundGroupSession.sessionKey();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
         assertNotNull(mAliceOutboundSessionKey);
         assertTrue(mAliceOutboundSessionKey.length() > 0);
     }
@@ -115,7 +128,7 @@ public class OlmGroupSessionTest {
         // alice encrypts a message to bob
         try {
             mAliceToBobMessage = mAliceOutboundGroupSession.encryptMessage(CLEAR_MESSAGE1);
-        } catch (OlmOutboundGroupSession.EncryptMessageException e) {
+        } catch (Exception e) {
             assertTrue("Exception in bob encryptMessage, Exception code=" + e.getMessage(), false);
         }
         assertFalse(TextUtils.isEmpty(mAliceToBobMessage));
@@ -275,7 +288,13 @@ public class OlmGroupSessionTest {
         assertNotNull(aliceOutboundGroupSession);
 
         // get the session key from the outbound group session
-        String sessionKeyRef = aliceOutboundGroupSession.sessionKey();
+        String sessionKeyRef = null;
+
+        try {
+            sessionKeyRef = aliceOutboundGroupSession.sessionKey();
+        } catch (Exception e) {
+            assertTrue(e.getMessage(), false);
+        }
         assertNotNull(sessionKeyRef);
 
         // bob creates INBOUND GROUP SESSION
@@ -286,7 +305,6 @@ public class OlmGroupSessionTest {
         }
         assertNotNull(bobInboundGroupSessionRef);
 
-
         // serialize alice session
         Context context = getInstrumentation().getContext();
         try {
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
index f31cab2df92b817a2c8fab3cecf1ef8fce3f8334..1a1b8abc65de0b94cee65d785595df886a150f8e 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
@@ -49,6 +49,9 @@ public class OlmException extends IOException {
     public static final int EXCEPTION_CODE_SESSION_IDENTIFIER = 30;
     public static final int EXCEPTION_CODE_SESSION_DECRYPT_SESSION = 31;
 
+    public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_IDENTIFIER = 40;
+    public static final int EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_KEY = 41;
+    public static final int EXCEPTION_CODE_OUTBOUND_GROUP_ENCRYPT_MESSAGE = 42;
 
     // exception human readable messages
     public static final String EXCEPTION_MSG_NEW_OUTBOUND_GROUP_SESSION = "createNewSession() failed";
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java
index f0536bde4f2812822c7bd69f4aba81aac3d92c4d..7ac38b23528f2a1087aae0b1d5092946060cf2a7 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java
@@ -209,8 +209,6 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
     protected String serialize(String aKey, StringBuffer aErrorMsg) {
         String pickleRetValue = null;
 
-        aErrorMsg.setLength(0);
-
         // sanity check
         if(null == aErrorMsg) {
             Log.e(LOG_TAG,"## serialize(): invalid parameter - aErrorMsg=null");
@@ -218,6 +216,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri
         } else if(TextUtils.isEmpty(aKey)) {
             aErrorMsg.append("Invalid input parameters in serialize()");
         } else {
+            aErrorMsg.setLength(0);
             try {
                 pickleRetValue = new String(serializeJni(aKey.getBytes("UTF-8")), "UTF-8");
             } catch (Exception e) {
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java
index 66a44d2c95101d19ac27896cc44cf24df5b70589..c27addbe4a1dca8bec0835aec2d97ec9f47044e6 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java
@@ -42,15 +42,6 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
      */
     private transient long mNativeId;
 
-    /**
-     * Exception triggered in {@link #encryptMessage(String)}
-     */
-    static public class EncryptMessageException extends Exception {
-        public EncryptMessageException(String message) {
-            super(message);
-        }
-    }
-
     /**
      * Constructor.<br>
      * Create and save a new session native instance ID and
@@ -60,10 +51,7 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
      */
     public OlmOutboundGroupSession() throws OlmException {
         if(createNewSession()) {
-            if( 0 != initOutboundGroupSession()) {
-                releaseSession();// prevent memory leak before throwing
-                throw new OlmException(OlmException.EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION, OlmException.EXCEPTION_MSG_INIT_OUTBOUND_GROUP_SESSION);
-            }
+            initOutboundGroupSession();
         } else {
             throw new OlmException(OlmException.EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION, OlmException.EXCEPTION_MSG_NEW_OUTBOUND_GROUP_SESSION);
         }
@@ -114,25 +102,29 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
 
     /**
      * Start a new outbound group session.<br>
-     * @return 0 if operation succeed, -1 otherwise
+     * @exception OlmException the failre reason
      */
-    private int initOutboundGroupSession() {
-        return initOutboundGroupSessionJni();
+    private void initOutboundGroupSession() throws OlmException {
+        try {
+            initOutboundGroupSessionJni();
+        } catch (Exception e) {
+            throw new OlmException(OlmException.EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION, e.getMessage());
+        }
     }
-    private native int initOutboundGroupSessionJni();
+
+    private native void initOutboundGroupSessionJni();
 
     /**
      * Get a base64-encoded identifier for this session.
-     * @return session identifier if operation succeed, null otherwise.
+     * @return session identifier
      */
-    public String sessionIdentifier() {
+    public String sessionIdentifier() throws OlmException {
         try {
             return new String(sessionIdentifierJni(), "UTF-8");
         } catch (Exception e) {
             Log.e(LOG_TAG, "## sessionIdentifier() failed " + e.getMessage());
+            throw new OlmException(OlmException.EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_IDENTIFIER, e.getMessage());
         }
-
-        return null;
     }
 
     private native byte[] sessionIdentifierJni();
@@ -153,15 +145,15 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
      * Each message is sent with a different ratchet key. This method returns the
      * ratchet key that will be used for the next message.
      * @return outbound session key
+     * @exception OlmException the failure reason
      */
-    public String sessionKey() {
+    public String sessionKey() throws OlmException {
         try {
             return new String(sessionKeyJni(), "UTF-8");
         } catch (Exception e) {
             Log.e(LOG_TAG, "## sessionKey() failed " + e.getMessage());
+            throw new OlmException(OlmException.EXCEPTION_CODE_OUTBOUND_GROUP_SESSION_KEY, e.getMessage());
         }
-
-        return null;
     }
 
     private native byte[] sessionKeyJni();
@@ -171,33 +163,27 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
      * The message given as parameter is encrypted and returned as the return value.
      * @param aClearMsg message to be encrypted
      * @return the encrypted message
-     * @exception EncryptMessageException the encryption failure reason
+     * @exception OlmException the encryption failure reason
      */
-    public String encryptMessage(String aClearMsg) throws EncryptMessageException {
+    public String encryptMessage(String aClearMsg) throws OlmException {
         String retValue = null;
 
         if (!TextUtils.isEmpty(aClearMsg)) {
-            StringBuffer errorMsg = new StringBuffer();
-
             try {
-                byte[] encryptedBuffer = encryptMessageJni(aClearMsg.getBytes("UTF-8"), errorMsg);
+                byte[] encryptedBuffer = encryptMessageJni(aClearMsg.getBytes("UTF-8"));
 
                 if (null != encryptedBuffer) {
                     retValue = new String(encryptedBuffer , "UTF-8");
                 }
             } catch (Exception e) {
                 Log.e(LOG_TAG, "## encryptMessage() failed " + e.getMessage());
-                errorMsg.append(e.getMessage());
-            }
-
-            if (0 != errorMsg.length()) {
-                throw new EncryptMessageException(errorMsg.toString());
+                throw new OlmException(OlmException.EXCEPTION_CODE_OUTBOUND_GROUP_ENCRYPT_MESSAGE, e.getMessage());
             }
         }
 
         return retValue;
     }
-    private native byte[] encryptMessageJni(byte[] aClearMsgBuffer, StringBuffer aErrorMsg);
+    private native byte[] encryptMessageJni(byte[] aClearMsgBuffer);
 
 
     //==============================================================================================================
@@ -242,9 +228,8 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
         } else if(TextUtils.isEmpty(aKey)) {
             aErrorMsg.append("Invalid input parameters in serialize()");
         } else {
-            aErrorMsg.setLength(0);
             try {
-                pickleRetValue = serializeJni(aKey.getBytes("UTF-8"), aErrorMsg);
+                pickleRetValue = serializeJni(aKey.getBytes("UTF-8"));
             } catch (Exception e) {
                 Log.e(LOG_TAG,"## serialize(): failed " + e.getMessage());
                 aErrorMsg.append(e.getMessage());
@@ -253,7 +238,7 @@ public class OlmOutboundGroupSession extends CommonSerializeUtils implements Ser
 
         return pickleRetValue;
     }
-    private native String serializeJni(byte[] aKey, StringBuffer aErrorMsg);
+    private native String serializeJni(byte[] aKey);
 
 
     /**
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.cpp
index 4168742eee62883951574a65188abf8a520b8b6b..982840c7c4b438bd5529aa87c5ea1fd4517fff03 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.cpp
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.cpp
@@ -84,11 +84,10 @@ JNIEXPORT jlong OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv
 
 /**
  * Start a new outbound session.<br>
- * @return ERROR_CODE_OK if operation succeed, ERROR_CODE_KO otherwise
  */
-JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(initOutboundGroupSessionJni)(JNIEnv *env, jobject thiz)
+JNIEXPORT void OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(initOutboundGroupSessionJni)(JNIEnv *env, jobject thiz)
 {
-    jint retCode = ERROR_CODE_KO;
+    const char* errorMessage = NULL;
 
     LOGD("## initOutboundGroupSessionJni(): IN");
 
@@ -97,6 +96,7 @@ JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(initOutboundGroupSessionJni)(
     if (!sessionPtr)
     {
         LOGE(" ## initOutboundGroupSessionJni(): failure - invalid outbound group session instance");
+        errorMessage = "invalid outbound group session instance";
     }
     else
     {
@@ -109,6 +109,7 @@ JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(initOutboundGroupSessionJni)(
         if ((0 != randomLength) && !setRandomInBuffer(env, &randomBuffPtr, randomLength))
         {
             LOGE(" ## initOutboundGroupSessionJni(): failure - random buffer init");
+            errorMessage = "random buffer init";
         }
         else
         {
@@ -120,11 +121,11 @@ JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(initOutboundGroupSessionJni)(
             size_t sessionResult = olm_init_outbound_group_session(sessionPtr, randomBuffPtr, randomLength);
 
             if (sessionResult == olm_error()) {
-                LOGE(" ## initOutboundGroupSessionJni(): failure - init outbound session creation  Msg=%s",(const char *)olm_outbound_group_session_last_error(sessionPtr));
+                errorMessage = (const char *)olm_outbound_group_session_last_error(sessionPtr);
+                LOGE(" ## initOutboundGroupSessionJni(): failure - init outbound session creation  Msg=%s", errorMessage);
             }
             else
             {
-                retCode = ERROR_CODE_OK;
                 LOGD(" ## initOutboundGroupSessionJni(): success - result=%lu", static_cast<long unsigned int>(sessionResult));
             }
 
@@ -132,7 +133,10 @@ JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(initOutboundGroupSessionJni)(
         }
     }
 
-    return retCode;
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
 }
 
 /**
@@ -142,12 +146,14 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(J
 {
     LOGD("## sessionIdentifierJni(): outbound group session IN");
 
+    const char* errorMessage = NULL;
     OlmOutboundGroupSession *sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz);
     jbyteArray returnValue = 0;
     
     if (!sessionPtr)
     {
         LOGE(" ## sessionIdentifierJni(): failure - invalid outbound group session instance");
+        errorMessage = "invalid outbound group session instance";
     }
     else
     {
@@ -160,6 +166,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(J
         if (!sessionIdPtr)
         {
            LOGE(" ## sessionIdentifierJni(): failure - outbound identifier allocation OOM");
+           errorMessage = "outbound identifier allocation OOM";
         }
         else
         {
@@ -167,7 +174,8 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(J
 
             if (result == olm_error())
             {
-                LOGE(" ## sessionIdentifierJni(): failure - outbound group session identifier failure Msg=%s",reinterpret_cast<const char*>(olm_outbound_group_session_last_error(sessionPtr)));
+                errorMessage = reinterpret_cast<const char*>(olm_outbound_group_session_last_error(sessionPtr));
+                LOGE(" ## sessionIdentifierJni(): failure - outbound group session identifier failure Msg=%s", errorMessage);
             }
             else
             {
@@ -185,6 +193,11 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(J
         }
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return returnValue;
 }
 
@@ -223,12 +236,14 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionKeyJni)(JNIEnv *
 {
     LOGD("## sessionKeyJni(): outbound group session IN");
 
+    const char* errorMessage = NULL;
     OlmOutboundGroupSession *sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz);
     jbyteArray returnValue = 0;
 
     if (!sessionPtr)
     {
         LOGE(" ## sessionKeyJni(): failure - invalid outbound group session instance");
+        errorMessage = "invalid outbound group session instance";
     }
     else
     {
@@ -241,6 +256,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionKeyJni)(JNIEnv *
         if (!sessionKeyPtr)
         {
            LOGE(" ## sessionKeyJni(): failure - session key allocation OOM");
+           errorMessage = "session key allocation OOM";
         }
         else
         {
@@ -248,7 +264,8 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionKeyJni)(JNIEnv *
 
             if (result == olm_error())
             {
-                LOGE(" ## sessionKeyJni(): failure - session key failure Msg=%s",(const char *)olm_outbound_group_session_last_error(sessionPtr));
+                errorMessage = (const char *)olm_outbound_group_session_last_error(sessionPtr);
+                LOGE(" ## sessionKeyJni(): failure - session key failure Msg=%s", errorMessage);
             }
             else
             {
@@ -265,44 +282,38 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionKeyJni)(JNIEnv *
         }
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return returnValue;
 }
 
-JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer, jobject aErrorMsg)
+JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer)
 {
     LOGD("## encryptMessageJni(): IN");
 
+    const char* errorMessage = NULL;
     jbyteArray encryptedMsgRet = 0;
 
     OlmOutboundGroupSession *sessionPtr = NULL;
     jbyte* clearMsgPtr = NULL;
 
-    jclass errorMsgJClass = 0;
-    jmethodID errorMsgMethodId = 0;
-
     if (!(sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz)))
     {
         LOGE(" ## encryptMessageJni(): failure - invalid outbound group session ptr=NULL");
-    }
-    else if (!aErrorMsg)
-    {
-        LOGE(" ## encryptMessageJni(): failure - invalid error output");
+        errorMessage = "invalid outbound group session ptr=NULL";
     }
     else if (!aClearMsgBuffer)
     {
         LOGE(" ## encryptMessageJni(): failure - invalid clear message");
+        errorMessage = "invalid clear message";
     }
     else if (!(clearMsgPtr = env->GetByteArrayElements(aClearMsgBuffer, NULL)))
     {
         LOGE(" ## encryptMessageJni(): failure - clear message JNI allocation OOM");
-    }
-    else if (!(errorMsgJClass = env->GetObjectClass(aErrorMsg)))
-    {
-        LOGE(" ## encryptMessageJni(): failure - unable to get error class");
-    }
-    else if (!(errorMsgMethodId = env->GetMethodID(errorMsgJClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;")))
-    {
-        LOGE(" ## encryptMessageJni(): failure - unable to get error method ID");
+        errorMessage = "clear message JNI allocation OOM";
     }
     else
     {
@@ -317,6 +328,7 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE
         if (!encryptedMsgPtr)
         {
             LOGE(" ## encryptMessageJni(): failure - encryptedMsgPtr buffer OOM");
+            errorMessage = "encryptedMsgPtr buffer OOM";
         }
         else
         {
@@ -331,15 +343,8 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE
 
             if (encryptedLength == olm_error())
             {
-                const char * errorMsgPtr = olm_outbound_group_session_last_error(sessionPtr);
-                LOGE(" ## encryptMessageJni(): failure - olm_group_decrypt_max_plaintext_length Msg=%s",errorMsgPtr);
-
-                jstring errorJstring = env->NewStringUTF(errorMsgPtr);
-
-                if (errorJstring)
-                {
-                    env->CallObjectMethod(aErrorMsg, errorMsgMethodId, errorJstring);
-                }
+                errorMessage = olm_outbound_group_session_last_error(sessionPtr);
+                LOGE(" ## encryptMessageJni(): failure - olm_group_decrypt_max_plaintext_length Msg=%s", errorMessage);
             }
             else
             {
@@ -362,6 +367,11 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE
         env->ReleaseByteArrayElements(aClearMsgBuffer, clearMsgPtr, JNI_ABORT);
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return encryptedMsgRet;
 }
 
@@ -369,15 +379,13 @@ JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIE
 /**
 * Serialize and encrypt session instance into a base64 string.<br>
 * @param aKey key used to encrypt the serialized session data
-* @param[out] aErrorMsg error message set if operation failed
 * @return a base64 string if operation succeed, null otherwise
 **/
-JNIEXPORT jstring OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer, jobject aErrorMsg)
+JNIEXPORT jstring OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKeyBuffer)
 {
+    const char* errorMessage = NULL;
+
     jstring pickledDataRetValue = 0;
-    jclass errorMsgJClass = 0;
-    jmethodID errorMsgMethodId = 0;
-    jstring errorJstring = 0;
     jbyte* keyPtr = NULL;
     OlmOutboundGroupSession* sessionPtr = NULL;
 
@@ -386,26 +394,17 @@ JNIEXPORT jstring OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env,
     if (!(sessionPtr = (OlmOutboundGroupSession*)getOutboundGroupSessionInstanceId(env,thiz)))
     {
         LOGE(" ## serializeJni(): failure - invalid session ptr");
+        errorMessage = "invalid session ptr";
     }
     else if (!aKeyBuffer)
     {
         LOGE(" ## serializeJni(): failure - invalid key");
-    }
-    else if (!aErrorMsg)
-    {
-        LOGE(" ## serializeJni(): failure - invalid error object");
-    }
-    else if (!(errorMsgJClass = env->GetObjectClass(aErrorMsg)))
-    {
-        LOGE(" ## serializeJni(): failure - unable to get error class");
-    }
-    else if (!(errorMsgMethodId = env->GetMethodID(errorMsgJClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;")))
-    {
-        LOGE(" ## serializeJni(): failure - unable to get error method ID");
+        errorMessage = "invalid key";
     }
     else if (!(keyPtr = env->GetByteArrayElements(aKeyBuffer, 0)))
     {
         LOGE(" ## serializeJni(): failure - keyPtr JNI allocation OOM");
+        errorMessage = "keyPtr JNI allocation OOM";
     }
     else
     {
@@ -419,6 +418,7 @@ JNIEXPORT jstring OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env,
         if(!pickledPtr)
         {
             LOGE(" ## serializeJni(): failure - pickledPtr buffer OOM");
+            errorMessage = "pickledPtr buffer OOM";
         }
         else
         {
@@ -429,13 +429,8 @@ JNIEXPORT jstring OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env,
                                                               pickledLength);
             if (result == olm_error())
             {
-                const char *errorMsgPtr = olm_outbound_group_session_last_error(sessionPtr);
-                LOGE(" ## serializeJni(): failure - olm_pickle_outbound_group_session() Msg=%s",errorMsgPtr);
-
-                if (!(errorJstring = env->NewStringUTF(errorMsgPtr)))
-                {
-                    env->CallObjectMethod(aErrorMsg, errorMsgMethodId, errorJstring);
-                }
+                errorMessage = olm_outbound_group_session_last_error(sessionPtr);
+                LOGE(" ## serializeJni(): failure - olm_pickle_outbound_group_session() Msg=%s", errorMessage);
             }
             else
             {
@@ -455,6 +450,11 @@ JNIEXPORT jstring OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env,
         env->ReleaseByteArrayElements(aKeyBuffer, keyPtr, JNI_ABORT);
     }
 
+    if (errorMessage)
+    {
+        env->ThrowNew(env->FindClass("java/lang/Exception"), errorMessage);
+    }
+
     return pickledDataRetValue;
 }
 
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.h
index f954bef4edbd99b5c058b1850dc81a896fdd52e1..1156b774605b7e44de4ad23090558489f6100eb9 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.h
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_outbound_group_session.h
@@ -32,15 +32,15 @@ extern "C" {
 JNIEXPORT void OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(releaseSessionJni)(JNIEnv *env, jobject thiz);
 JNIEXPORT jlong OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv *env, jobject thiz);
 
-JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(initOutboundGroupSessionJni)(JNIEnv *env, jobject thiz);
+JNIEXPORT void OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(initOutboundGroupSessionJni)(JNIEnv *env, jobject thiz);
 JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(JNIEnv *env, jobject thiz);
 JNIEXPORT jint OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(messageIndexJni)(JNIEnv *env, jobject thiz);
 JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(sessionKeyJni)(JNIEnv *env, jobject thiz);
 
-JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer, jobject aErrorMsg);
+JNIEXPORT jbyteArray OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jbyteArray aClearMsgBuffer);
 
 // serialization
-JNIEXPORT jstring OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey, jobject aErrorMsg);
+JNIEXPORT jstring OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(serializeJni)(JNIEnv *env, jobject thiz, jbyteArray aKey);
 JNIEXPORT jstring OLM_OUTBOUND_GROUP_SESSION_FUNC_DEF(deserializeJni)(JNIEnv *env, jobject thiz, jbyteArray aSerializedData, jbyteArray aKey);
 
 #ifdef __cplusplus