diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index b50ee5fc77e043faac1c7c27294652667cd4a1ab..c08e15b64a85dad88cae222d6b2a57536dc295d5 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -3277,7 +3277,7 @@ pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint,
 	ast_assert(status != NULL);
 
 	contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
-	if (ast_sip_set_tpselector_from_ep_or_uri(endpoint, pjsip_uri_get_uri(contact_hdr->uri),
+	if (!contact_hdr || ast_sip_set_tpselector_from_ep_or_uri(endpoint, pjsip_uri_get_uri(contact_hdr->uri),
 		&selector)) {
 		return NULL;
 	}
diff --git a/res/res_pjsip/pjsip_message_filter.c b/res/res_pjsip/pjsip_message_filter.c
index 085d9787ee6f201d97a7b00c69f74eeddecb25cb..427aec7404423cec3638ad269274573c86a03ebe 100644
--- a/res/res_pjsip/pjsip_message_filter.c
+++ b/res/res_pjsip/pjsip_message_filter.c
@@ -429,15 +429,27 @@ static pj_bool_t on_rx_process_uris(pjsip_rx_data *rdata)
 		return PJ_TRUE;
 	}
 
-	while ((contact =
-		(pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
-			contact ? contact->next : NULL))) {
+
+	contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(
+		rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
+
+	if (!contact && pjsip_method_creates_dialog(&rdata->msg_info.msg->line.req.method)) {
+		/* A contact header is required for dialog creating methods */
+		static const pj_str_t missing_contact = { "Missing Contact header", 22 };
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 400,
+				&missing_contact, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	while (contact) {
 		if (!contact->star && !is_sip_uri(contact->uri)) {
 			print_uri_debug(URI_TYPE_CONTACT, rdata, (pjsip_hdr *)contact);
 			pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata,
 				PJSIP_SC_UNSUPPORTED_URI_SCHEME, NULL, NULL, NULL);
 			return PJ_TRUE;
 		}
+		contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(
+			rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next);
 	}
 
 	return PJ_FALSE;
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index 45ba605d46db001ab762ce49abaa87864fd994df..1f24de050bc2783a65e311f1838a90bfa8d0f2b4 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -613,8 +613,12 @@ static void subscription_persistence_update(struct sip_subscription_tree *sub_tr
 		expires = expires_hdr ? expires_hdr->ivalue : DEFAULT_PUBLISH_EXPIRES;
 		sub_tree->persistence->expires = ast_tvadd(ast_tvnow(), ast_samp2tv(expires, 1));
 
-		pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contact_hdr->uri,
-			sub_tree->persistence->contact_uri, sizeof(sub_tree->persistence->contact_uri));
+		if (contact_hdr) {
+			pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contact_hdr->uri,
+					sub_tree->persistence->contact_uri, sizeof(sub_tree->persistence->contact_uri));
+		} else {
+			ast_log(LOG_WARNING, "Contact not updated due to missing contact header\n");
+		}
 
 		/* When receiving a packet on an streaming transport, it's possible to receive more than one SIP
 		 * message at a time into the rdata->pkt_info.packet buffer. However, the rdata->msg_info.msg_buf