diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h
index 664e347cf2657284411be26b7a3916c6f9c216c1..832500c31e7bd423d3aa8526e3b0d87a4f49b4b2 100644
--- a/include/asterisk/utils.h
+++ b/include/asterisk/utils.h
@@ -1089,4 +1089,14 @@ char *ast_crypt_encrypt(const char *key);
  */
 int ast_crypt_validate(const char *key, const char *expected);
 
+/*
+ * \brief Test that a file exists and is readable by the effective user.
+ * \since 13.7.0
+ *
+ * \param filename File to test.
+ * \return True (non-zero) if the file exists and is readable.
+ * \return False (zero) if the file either doesn't exists or is not readable.
+ */
+int ast_file_is_readable(const char *filename);
+
 #endif /* _ASTERISK_UTILS_H */
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 57a3ef354aac650bbc1948cb27bb1d482d62e530..beda8cd745651d0ae67531ca5935446853973211 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -1634,18 +1634,34 @@ int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name,
 		}
 	} else if (!strcasecmp(name, "dtlscertfile")) {
 		ast_free(dtls_cfg->certfile);
+		if (!ast_file_is_readable(value)) {
+			ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
+			return -1;
+		}
 		dtls_cfg->certfile = ast_strdup(value);
 	} else if (!strcasecmp(name, "dtlsprivatekey")) {
 		ast_free(dtls_cfg->pvtfile);
+		if (!ast_file_is_readable(value)) {
+			ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
+			return -1;
+		}
 		dtls_cfg->pvtfile = ast_strdup(value);
 	} else if (!strcasecmp(name, "dtlscipher")) {
 		ast_free(dtls_cfg->cipher);
 		dtls_cfg->cipher = ast_strdup(value);
 	} else if (!strcasecmp(name, "dtlscafile")) {
 		ast_free(dtls_cfg->cafile);
+		if (!ast_file_is_readable(value)) {
+			ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
+			return -1;
+		}
 		dtls_cfg->cafile = ast_strdup(value);
 	} else if (!strcasecmp(name, "dtlscapath") || !strcasecmp(name, "dtlscadir")) {
 		ast_free(dtls_cfg->capath);
+		if (!ast_file_is_readable(value)) {
+			ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
+			return -1;
+		}
 		dtls_cfg->capath = ast_strdup(value);
 	} else if (!strcasecmp(name, "dtlssetup")) {
 		if (!strcasecmp(value, "active")) {
diff --git a/main/utils.c b/main/utils.c
index ffef3ac976b2a9e7a207d92c96f64110ee8236a8..3eeafed4fb92ea8866f32e708115a92df5789fb2 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -2932,3 +2932,20 @@ int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2)
 {
 	return memcmp(eid1, eid2, sizeof(*eid1));
 }
+
+int ast_file_is_readable(const char *filename)
+{
+#if defined(HAVE_EACCESS) || defined(HAVE_EUIDACCESS)
+#if defined(HAVE_EUIDACCESS) && !defined(HAVE_EACCESS)
+#define eaccess euidaccess
+#endif
+	return eaccess(filename, R_OK) == 0;
+#else
+	int fd = open(filename, O_RDONLY |  O_NONBLOCK);
+	if (fd < 0) {
+		return 0;
+	}
+	close(fd);
+	return 1;
+#endif
+}
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index e2f0c7f4347cfac0db759005bf25017569904774..d8ece1509441e114a2fa97c8531d885bb6c4ba4c 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -27,6 +27,7 @@
 #include "asterisk/astobj2.h"
 #include "asterisk/sorcery.h"
 #include "asterisk/acl.h"
+#include "asterisk/utils.h"
 #include "include/res_pjsip_private.h"
 #include "asterisk/http_websocket.h"
 
@@ -224,8 +225,22 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
 					ast_sorcery_object_get_id(obj));
 			return -1;
 		}
+		if (!ast_strlen_zero(transport->ca_list_file)) {
+			if (!ast_file_is_readable(transport->ca_list_file)) {
+				ast_log(LOG_ERROR, "Transport: %s: ca_list_file %s is either missing or not readable\n",
+						ast_sorcery_object_get_id(obj), transport->ca_list_file);
+				return -1;
+			}
+		}
 		transport->tls.ca_list_file = pj_str((char*)transport->ca_list_file);
 #ifdef HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2
+		if (!ast_strlen_zero(transport->ca_list_path)) {
+			if (!ast_file_is_readable(transport->ca_list_path)) {
+				ast_log(LOG_ERROR, "Transport: %s: ca_list_path %s is either missing or not readable\n",
+						ast_sorcery_object_get_id(obj), transport->ca_list_path);
+				return -1;
+			}
+		}
 		transport->tls.ca_list_path = pj_str((char*)transport->ca_list_path);
 #else
 		if (!ast_strlen_zero(transport->ca_list_path)) {
@@ -233,7 +248,21 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
 					"support the 'ca_list_path' option. Please upgrade to version 2.4 or later.\n");
 		}
 #endif
+		if (!ast_strlen_zero(transport->cert_file)) {
+			if (!ast_file_is_readable(transport->cert_file)) {
+				ast_log(LOG_ERROR, "Transport: %s: cert_file %s is either missing or not readable\n",
+						ast_sorcery_object_get_id(obj), transport->cert_file);
+				return -1;
+			}
+		}
 		transport->tls.cert_file = pj_str((char*)transport->cert_file);
+		if (!ast_strlen_zero(transport->privkey_file)) {
+			if (!ast_file_is_readable(transport->privkey_file)) {
+				ast_log(LOG_ERROR, "Transport: %s: privkey_file %s is either missing or not readable\n",
+						ast_sorcery_object_get_id(obj), transport->privkey_file);
+				return -1;
+			}
+		}
 		transport->tls.privkey_file = pj_str((char*)transport->privkey_file);
 		transport->tls.password = pj_str((char*)transport->password);
 		set_qos(transport, &transport->tls.qos_params);
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 1b0d6e2e94e366dc4c4b24b6a9d790c4dd65750d..746a45742e84af95168be553f884c77e72eaf8ac 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -683,7 +683,7 @@ static int media_encryption_handler(const struct aco_option *opt, struct ast_var
 		endpoint->media.rtp.encryption = AST_SIP_MEDIA_ENCRYPT_SDES;
 	} else if (!strcasecmp("dtls", var->value)) {
 		endpoint->media.rtp.encryption = AST_SIP_MEDIA_ENCRYPT_DTLS;
-		ast_rtp_dtls_cfg_parse(&endpoint->media.rtp.dtls_cfg, "dtlsenable", "yes");
+		return ast_rtp_dtls_cfg_parse(&endpoint->media.rtp.dtls_cfg, "dtlsenable", "yes");
 	} else {
 		return -1;
 	}