diff --git a/src/opus.h b/src/opus.h
index 17934bff7048a4b03e6c705b644671f479654831..fb49b0b1fe0fa0654a8121cc8e2a9d7db009c41d 100644
--- a/src/opus.h
+++ b/src/opus.h
@@ -185,10 +185,11 @@ OPUS_EXPORT int opus_encoder_get_size(int channels);
 OPUS_EXPORT OpusEncoder *opus_encoder_create(
     int Fs,                     /* Sampling rate of input signal (Hz) */
     int channels,               /* Number of channels (1/2) in input signal */
-    int application             /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
+    int application,            /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
+    int *error                  /* Error code */
 );
 
-OPUS_EXPORT OpusEncoder *opus_encoder_init(
+OPUS_EXPORT int opus_encoder_init(
     OpusEncoder *st,            /* Encoder state */
     int Fs,                     /* Sampling rate of input signal (Hz) */
     int channels,               /* Number of channels (1/2) in input signal */
@@ -223,10 +224,11 @@ OPUS_EXPORT int opus_decoder_get_size(int channels);
 
 OPUS_EXPORT OpusDecoder *opus_decoder_create(
     int Fs,                     /* Sampling rate of output signal (Hz) */
-    int channels                /* Number of channels (1/2) in output signal */
+    int channels,               /* Number of channels (1/2) in output signal */
+    int *error                  /* Error code*/
 );
 
-OPUS_EXPORT OpusDecoder *opus_decoder_init(OpusDecoder *st,
+OPUS_EXPORT int opus_decoder_init(OpusDecoder *st,
     int Fs,                     /* Sampling rate of output signal (Hz) */
     int channels                /* Number of channels (1/2) in output signal */
 );
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index e3b12e2b57beeb0a0d4ab4eb14777e195ba27551..b45012947613289bba2f4286c214301a322b3ec9 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -86,19 +86,19 @@ int opus_decoder_get_size(int channels)
 
 }
 
-OpusDecoder *opus_decoder_init(OpusDecoder *st, int Fs, int channels)
+int opus_decoder_init(OpusDecoder *st, int Fs, int channels)
 {
 	void *silk_dec;
 	CELTDecoder *celt_dec;
 	int ret, silkDecSizeBytes;
 
 	if (channels<1 || channels > 2)
-	    return NULL;
+	    return OPUS_BAD_ARG;
 	memset(st, 0, opus_decoder_get_size(channels));
 	/* Initialize SILK encoder */
     ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
     if( ret ) {
-        return NULL;
+        return OPUS_INTERNAL_ERROR;
     }
     silkDecSizeBytes = align(silkDecSizeBytes);
     st->silk_dec_offset = align(sizeof(OpusDecoder));
@@ -123,18 +123,29 @@ OpusDecoder *opus_decoder_init(OpusDecoder *st, int Fs, int channels)
 
 	st->prev_mode = 0;
 	st->frame_size = Fs/400;
-	return st;
+	return OPUS_OK;
 failure:
     free(st);
-    return NULL;
+    return OPUS_INTERNAL_ERROR;
 }
 
-OpusDecoder *opus_decoder_create(int Fs, int channels)
+OpusDecoder *opus_decoder_create(int Fs, int channels, int *error)
 {
-    char *raw_state = (char*)malloc(opus_decoder_get_size(channels));
-    if (raw_state == NULL)
-    	return NULL;
-    return opus_decoder_init((OpusDecoder*)raw_state, Fs, channels);
+   int ret;
+   char *raw_state = (char*)malloc(opus_decoder_get_size(channels));
+   if (raw_state == NULL)
+   {
+      if (error)
+         *error = OPUS_ALLOC_FAIL;
+      return NULL;
+   }
+   ret = opus_decoder_init((OpusDecoder*)raw_state, Fs, channels);
+   if (ret != OPUS_OK)
+   {
+      free(raw_state);
+      raw_state = NULL;
+   }
+   return (OpusDecoder*)raw_state;
 }
 
 static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2, opus_val16 *out,
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index 7d45cc25fa81392afdb19b433785761972264632..dd7487ce382f3cec531dbca5adc892cb8b9e4aa6 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -110,7 +110,7 @@ int opus_encoder_get_size(int channels)
     return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes;
 }
 
-OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int application)
+int opus_encoder_init(OpusEncoder* st, int Fs, int channels, int application)
 {
     void *silk_enc;
     CELTEncoder *celt_enc;
@@ -118,17 +118,17 @@ OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int applic
     int ret, silkEncSizeBytes;
 
     if (channels > 2 || channels < 1)
-        return NULL;
+        return OPUS_BAD_ARG;
     if (application < OPUS_APPLICATION_VOIP || application > OPUS_APPLICATION_AUDIO)
-        return NULL;
+        return OPUS_BAD_ARG;
     if (Fs != 8000 && Fs != 12000 && Fs != 16000 && Fs != 24000 && Fs != 48000)
-        return NULL;
+        return OPUS_BAD_ARG;
 
     memset(st, 0, opus_encoder_get_size(channels));
     /* Create SILK encoder */
     ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
     if (ret)
-        return NULL;
+        return OPUS_BAD_ARG;
     silkEncSizeBytes = align(silkEncSizeBytes);
     st->silk_enc_offset = align(sizeof(OpusEncoder));
     st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes;
@@ -190,11 +190,11 @@ OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int applic
     else
        st->delay_compensation += 2;
 
-    return st;
+    return OPUS_OK;
 
 failure:
     free(st);
-    return NULL;
+    return OPUS_INTERNAL_ERROR;
 }
 
 static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels)
@@ -228,12 +228,25 @@ static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channel
    toc |= (channels==2)<<2;
    return toc;
 }
-OpusEncoder *opus_encoder_create(int Fs, int channels, int mode)
+OpusEncoder *opus_encoder_create(int Fs, int channels, int mode, int *error)
 {
-    char *raw_state = (char *)malloc(opus_encoder_get_size(channels));
-    if (raw_state == NULL)
-        return NULL;
-    return opus_encoder_init((OpusEncoder*)raw_state, Fs, channels, mode);
+   int ret;
+   char *raw_state = (char *)malloc(opus_encoder_get_size(channels));
+   if (raw_state == NULL)
+   {
+      if (error)
+         *error = OPUS_ALLOC_FAIL;
+      return NULL;
+   }
+   ret = opus_encoder_init((OpusEncoder*)raw_state, Fs, channels, mode);
+   if (error)
+      *error = ret;
+   if (ret != OPUS_OK)
+   {
+      free(raw_state);
+      raw_state = NULL;
+   }
+   return (OpusEncoder*)raw_state;
 }
 #ifdef FIXED_POINT
 int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
diff --git a/src/test_opus.c b/src/test_opus.c
index 9e73202fe536031779ceb02a170f5a61d3d02f59..3a84fafc8c4a5ad1494caab06a4acc5e93ac6ac1 100644
--- a/src/test_opus.c
+++ b/src/test_opus.c
@@ -257,8 +257,18 @@ int main(int argc, char *argv[])
         return 1;
     }
 
-    enc = opus_encoder_create(sampling_rate, channels, application);
-    dec = opus_decoder_create(sampling_rate, channels);
+    enc = opus_encoder_create(sampling_rate, channels, application, &err);
+    if (err != OPUS_OK)
+    {
+       fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
+       return 1;
+    }
+    dec = opus_decoder_create(sampling_rate, channels, &err);
+    if (err != OPUS_OK)
+    {
+       fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
+       return 1;
+    }
 
     if (enc==NULL)
     {