diff --git a/src/transport.c b/src/transport.c
index 057dcf5..639984c 100644
--- a/src/transport.c
+++ b/src/transport.c
@@ -142,6 +142,7 @@ decrypt(LIBSSH2_SESSION * session, unsigned char *source,
         if (session->remote.crypt->crypt(session, source,
                                          &session->remote.crypt_abstract)) {
             LIBSSH2_FREE(session, p->payload);
+            p->payload = NULL;
             return LIBSSH2_ERROR_DECRYPT;
         }
 
@@ -217,6 +218,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
                                               session->fullpacket_payload_len,
                                               &session->remote.comp_abstract);
             LIBSSH2_FREE(session, p->payload);
+            p->payload = NULL;
             if(rc)
                 return rc;
 
@@ -448,6 +450,13 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
                 return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
             }
 
+            /* If a packet was already allocated we must free it now.
+             * It would be nicer to keep track of allocated size, and
+             * only realloc when really neccessary.
+             */
+            if (p->payload)
+                LIBSSH2_FREE(session, p->payload);
+
             /* Get a packet handle put data into. We get one to
                hold all data, including padding and MAC. */
             p->payload = LIBSSH2_ALLOC(session, total_num);

