diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 7b605b982884158a233869460597d203d290723a..bbb286acf42ecac11f71254f85e1bb0e8b9183a0 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -358,6 +358,8 @@ struct sip_outbound_registration_client_state {
 	unsigned int auth_attempted:1;
 	/*! \brief The name of the transport to be used for the registration */
 	char *transport_name;
+	/*! \brief The name of the registration sorcery object */
+	char *registration_name;
 };
 
 /*! \brief Outbound registration state information (persists for lifetime that registration should exist) */
@@ -795,6 +797,82 @@ static void schedule_retry(struct registration_response *response, unsigned int
 	}
 }
 
+static int reregister_immediately_cb(void *obj)
+{
+	struct sip_outbound_registration_state *state = obj;
+
+	if (state->client_state->status != SIP_REGISTRATION_REGISTERED) {
+		ao2_ref(state, -1);
+		return 0;
+	}
+
+	if (DEBUG_ATLEAST(1)) {
+		pjsip_regc_info info;
+
+		pjsip_regc_get_info(state->client_state->client, &info);
+		ast_log(LOG_DEBUG,
+			"Outbound registration transport to server '%.*s' from client '%.*s' shutdown\n",
+			(int) info.server_uri.slen, info.server_uri.ptr,
+			(int) info.client_uri.slen, info.client_uri.ptr);
+	}
+
+	cancel_registration(state->client_state);
+
+	ao2_ref(state->client_state, +1);
+	handle_client_registration(state->client_state);
+
+	ao2_ref(state, -1);
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief The reliable transport we registered using has shutdown.
+ * \since 13.18.0
+ *
+ * \param obj What is needed to initiate a reregister attempt.
+ *
+ * \return Nothing
+ */
+static void registration_transport_shutdown_cb(void *obj)
+{
+	const char *registration_name = obj;
+	struct sip_outbound_registration_state *state;
+
+	state = get_state(registration_name);
+	if (!state) {
+		/* Registration no longer exists or shutting down. */
+		return;
+	}
+	if (ast_sip_push_task(state->client_state->serializer, reregister_immediately_cb, state)) {
+		ao2_ref(state, -1);
+	}
+}
+
+static void registration_transport_monitor_setup(pjsip_transport *transport, const char *registration_name)
+{
+	char *monitor;
+
+	if (!PJSIP_TRANSPORT_IS_RELIABLE(transport)) {
+		return;
+	}
+	monitor = ao2_alloc_options(strlen(registration_name) + 1, NULL,
+		AO2_ALLOC_OPT_LOCK_NOLOCK);
+	if (!monitor) {
+		return;
+	}
+	strcpy(monitor, registration_name);/* Safe */
+
+	/*
+	 * We'll ignore if the transport has already been shutdown before we
+	 * register the monitor.  We might get into a message spamming infinite
+	 * loop of registration, shutdown, reregistration...
+	 */
+	ast_sip_transport_monitor_register(transport, registration_transport_shutdown_cb,
+		monitor);
+	ao2_ref(monitor, -1);
+}
+
 /*! \brief Callback function for handling a response to a registration attempt */
 static int handle_registration_response(void *data)
 {
@@ -863,9 +941,15 @@ static int handle_registration_response(void *data)
 				next_registration_round = 0;
 			}
 			schedule_registration(response->client_state, next_registration_round);
+
+			/* See if we should monitor for transport shutdown */
+			registration_transport_monitor_setup(response->rdata->tp_info.transport,
+				response->client_state->registration_name);
 		} else {
 			ast_debug(1, "Outbound unregistration to '%s' with client '%s' successful\n", server_uri, client_uri);
 			update_client_state_status(response->client_state, SIP_REGISTRATION_UNREGISTERED);
+			ast_sip_transport_monitor_unregister(response->rdata->tp_info.transport,
+				registration_transport_shutdown_cb);
 		}
 	} else if (response->client_state->destroy) {
 		/* We need to deal with the pending destruction instead. */
@@ -1008,12 +1092,13 @@ static void sip_outbound_registration_client_state_destroy(void *obj)
 {
 	struct sip_outbound_registration_client_state *client_state = obj;
 
-	ast_free(client_state->transport_name);
 	ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "-1", 1.0);
 	ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "-1", 1.0,
 		sip_outbound_registration_status_str(client_state->status));
 
 	ast_taskprocessor_unreference(client_state->serializer);
+	ast_free(client_state->transport_name);
+	ast_free(client_state->registration_name);
 }
 
 /*! \brief Allocator function for registration state */
@@ -1033,6 +1118,23 @@ static struct sip_outbound_registration_state *sip_outbound_registration_state_a
 		return NULL;
 	}
 
+	state->client_state->status = SIP_REGISTRATION_UNREGISTERED;
+	state->client_state->timer.user_data = state->client_state;
+	state->client_state->timer.cb = sip_outbound_registration_timer_cb;
+	state->client_state->transport_name = ast_strdup(registration->transport);
+	state->client_state->registration_name =
+		ast_strdup(ast_sorcery_object_get_id(registration));
+
+	ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "+1", 1.0);
+	ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "+1", 1.0,
+		sip_outbound_registration_status_str(state->client_state->status));
+
+	if (!state->client_state->transport_name
+		|| !state->client_state->registration_name) {
+		ao2_cleanup(state);
+		return NULL;
+	}
+
 	/* Create name with seq number appended. */
 	ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/outreg/%s",
 		ast_sorcery_object_get_id(registration));
@@ -1043,14 +1145,6 @@ static struct sip_outbound_registration_state *sip_outbound_registration_state_a
 		ao2_cleanup(state);
 		return NULL;
 	}
-	state->client_state->status = SIP_REGISTRATION_UNREGISTERED;
-	state->client_state->timer.user_data = state->client_state;
-	state->client_state->timer.cb = sip_outbound_registration_timer_cb;
-	state->client_state->transport_name = ast_strdup(registration->transport);
-
-	ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "+1", 1.0);
-	ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "+1", 1.0,
-		sip_outbound_registration_status_str(state->client_state->status));
 
 	state->registration = ao2_bump(registration);
 	return state;
@@ -2054,6 +2148,8 @@ static int unload_module(void)
 
 	ao2_global_obj_release(current_states);
 
+	ast_sip_transport_monitor_unregister_all(registration_transport_shutdown_cb);
+
 	/* Wait for registration serializers to get destroyed. */
 	ast_debug(2, "Waiting for registration transactions to complete for unload.\n");
 	remaining = ast_serializer_shutdown_group_join(shutdown_group, MAX_UNLOAD_TIMEOUT_TIME);