diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index 55401e7c7a53a8b118d9edebbb295ca0918f31f3..5ca2c99a5295616ce31dd4d60019378396742f5f 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -408,9 +408,10 @@ struct ast_sip_channel_pvt *ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_
  * \param endpoint The endpoint that this session communicates with
  * \param contact The contact associated with this session
  * \param inv_session The PJSIP INVITE session data
+ * \param rdata INVITE request received (NULL if for outgoing allocation)
  */
 struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
-	struct ast_sip_contact *contact, pjsip_inv_session *inv);
+	struct ast_sip_contact *contact, pjsip_inv_session *inv, pjsip_rx_data *rdata);
 
 /*!
  * \brief Request and wait for the session serializer to be suspended.
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 59d759fdc9f4c09724ed4b8cdee496859f867bca..67cd09ddfd8f226bb89f362581024e3ae5c5bff1 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -1403,12 +1403,11 @@ struct ast_sip_channel_pvt *ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_
 }
 
 struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
-	struct ast_sip_contact *contact, pjsip_inv_session *inv_session)
+	struct ast_sip_contact *contact, pjsip_inv_session *inv_session, pjsip_rx_data *rdata)
 {
 	RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
 	struct ast_sip_session_supplement *iter;
 	int dsp_features = 0;
-	char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
 
 	session = ao2_alloc(sizeof(*session), session_destructor);
 	if (!session) {
@@ -1429,11 +1428,24 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
 	/* fill session->media with available types */
 	ao2_callback(sdp_handlers, OBJ_NODATA, add_session_media, session);
 
-	/* Create name with seq number appended. */
-	ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/session/%s",
-		ast_sorcery_object_get_id(endpoint));
+	if (rdata) {
+		/*
+		 * We must continue using the serializer that the original
+		 * INVITE came in on for the dialog.  There may be
+		 * retransmissions already enqueued in the original
+		 * serializer that can result in reentrancy and message
+		 * sequencing problems.
+		 */
+		session->serializer = ast_sip_get_distributor_serializer(rdata);
+	} else {
+		char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
 
-	session->serializer = ast_sip_create_serializer(tps_name);
+		/* Create name with seq number appended. */
+		ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/outsess/%s",
+			ast_sorcery_object_get_id(endpoint));
+
+		session->serializer = ast_sip_create_serializer(tps_name);
+	}
 	if (!session->serializer) {
 		return NULL;
 	}
@@ -1731,7 +1743,9 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint
 	timer.sess_expires = endpoint->extensions.timer.sess_expires;
 	pjsip_timer_init_session(inv_session, &timer);
 
-	if (!(session = ast_sip_session_alloc(endpoint, found_contact ? found_contact : contact, inv_session))) {
+	session = ast_sip_session_alloc(endpoint, found_contact ? found_contact : contact,
+		inv_session, NULL);
+	if (!session) {
 		pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
 		return NULL;
 	}
@@ -2142,7 +2156,7 @@ static void handle_new_invite_request(pjsip_rx_data *rdata)
 		return;
 	}
 
-	session = ast_sip_session_alloc(endpoint, NULL, inv_session);
+	session = ast_sip_session_alloc(endpoint, NULL, inv_session, rdata);
 	if (!session) {
 		if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
 			pjsip_inv_terminate(inv_session, 500, PJ_FALSE);