diff --git a/lib/SimpleSAML/Error/NoAvailableIDP.php b/lib/SimpleSAML/Error/NoAvailableIDP.php
new file mode 100644
index 0000000000000000000000000000000000000000..d3c99dc237a44161718e2b31a6e2fe8d23b289b5
--- /dev/null
+++ b/lib/SimpleSAML/Error/NoAvailableIDP.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Simple exception to model the NoAvailableIDP SAML error.
+ *
+ * @author Jaime PĂ©rez Crespo, UNINETT AS <jaime.perez@uninett.no>
+ * @package SimpleSAMLphp
+ */
+
+namespace SimpleSAML\Error;
+
+
+class NoAvailableIDP extends \SimpleSAML_Error_Exception
+{
+
+}
\ No newline at end of file
diff --git a/lib/SimpleSAML/Error/NoSupportedIDP.php b/lib/SimpleSAML/Error/NoSupportedIDP.php
new file mode 100644
index 0000000000000000000000000000000000000000..0ef97ed2acfbafe4d15acc7c765e5f0b44f12947
--- /dev/null
+++ b/lib/SimpleSAML/Error/NoSupportedIDP.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Simple exception to model the NoSupportedIDP SAML error.
+ *
+ * @author Jaime PĂ©rez Crespo, UNINETT AS <jaime.perez@uninett.no>
+ * @package SimpleSAMLphp
+ */
+
+namespace SimpleSAML\Error;
+
+
+class NoSupportedIDP extends \SimpleSAML_Error_Exception
+{
+
+}
\ No newline at end of file
diff --git a/modules/saml/lib/Auth/Source/SP.php b/modules/saml/lib/Auth/Source/SP.php
index 4a091fdb56d0b39c3d28b830f8321ca7fe4c030f..99827f59c17eb476b19607afdf4c3121b94a5154 100644
--- a/modules/saml/lib/Auth/Source/SP.php
+++ b/modules/saml/lib/Auth/Source/SP.php
@@ -385,8 +385,23 @@ class sspmod_saml_Auth_Source_SP extends SimpleSAML_Auth_Source {
 			$idp = (string)$state['saml:idp'];
 		}
 
-		if ($idp === NULL && isset($state['saml:IDPList']) && sizeof($state['saml:IDPList']) == 1) {
-			$idp = $state['saml:IDPList'][0];
+		if (isset($state['saml:IDPList']) && sizeof($state['saml:IDPList']) > 0) {
+			// we have a SAML IDPList (we are a proxy): filter the list of IdPs available
+			$mdh = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+			$known_idps = $mdh->getList();
+			$intersection = array_intersect($state['saml:IDPList'], array_keys($known_idps));
+
+			if (empty($intersection)) { // all requested IdPs are unknown
+				throw new SimpleSAML\Error\NoSupportedIDP('None of the IdPs requested are supported by this proxy.');
+			}
+
+			if (!is_null($idp) && !in_array($idp, $intersection)) { // the IdP is enforced but not in the IDPList
+				throw new SimpleSAML\Error\NoAvailableIDP('None of the IdPs requested are available to this proxy.');
+			}
+
+			if (is_null($idp) && sizeof($intersection) === 1) { // only one IdP requested or valid
+				$idp = current($state['saml:IDPList']);
+			}
 		}
 
 		if ($idp === NULL) {
@@ -422,9 +437,30 @@ class sspmod_saml_Auth_Source_SP extends SimpleSAML_Auth_Source {
 		{
 			/*
 			 * The user has an existing, valid session. However, the SP provided a list of IdPs it accepts for
-			 * authentication, and the IdP the existing session is related to is not in that list. We need to
-			 * inform the user, and ask whether we should logout before starting the authentication process again
-			 * with a different IdP, or cancel the current SSO attempt.
+			 * authentication, and the IdP the existing session is related to is not in that list.
+			 *
+			 * First, check if we recognize any of the IdPs requested.
+			 */
+
+			$mdh = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+			$known_idps = $mdh->getList();
+			$intersection = array_intersect($state['saml:IDPList'], array_keys($known_idps));
+
+			if (empty($intersection)) { // all requested IdPs are unknown
+				throw new SimpleSAML\Error\NoSupportedIDP('None of the IdPs requested are supported by this proxy.');
+			}
+
+			/*
+			 * We have at least one IdP in the IDPList that we recognize, and it's not the one currently in use. Let's
+			 * see if this proxy enforces the use of one single IdP.
+			 */
+			if (!is_null($this->idp) && !in_array($this->idp, $intersection)) { // an IdP is enforced but not requested
+				throw new SimpleSAML\Error\NoAvailableIDP('None of the IdPs requested are available to this proxy.');
+			}
+
+			/*
+			 * We need to inform the user, and ask whether we should logout before starting the authentication process
+			 * again with a different IdP, or cancel the current SSO attempt.
 			 */
 			SimpleSAML\Logger::warning(
 				"Reauthentication after logout is needed. The IdP '${state['saml:sp:IdP']}' is not in the IDPList ".
diff --git a/modules/saml/lib/Error.php b/modules/saml/lib/Error.php
index 78799a2cd7b41bcb6af2b870f1fadeb844e0e25f..8cf0fb15ff2d68dad44ab7b9071c82eaf3163835 100644
--- a/modules/saml/lib/Error.php
+++ b/modules/saml/lib/Error.php
@@ -117,8 +117,21 @@ class sspmod_saml_Error extends SimpleSAML_Error_Exception {
 				\SAML2\Constants::STATUS_PROXY_COUNT_EXCEEDED,
 				$exception->getMessage(),
 				$exception
-				);
-
+			);
+		} elseif ($exception instanceof SimpleSAML\Error\NoAvailableIDP) {
+			$e = new self(
+				\SAML2\Constants::STATUS_RESPONDER,
+				\SAML2\Constants::STATUS_NO_AVAILABLE_IDP,
+				$exception->getMessage(),
+				$exception
+			);
+		} elseif ($exception instanceof SimpleSAML\Error\NoSupportedIDP) {
+			$e = new self(
+				\SAML2\Constants::STATUS_RESPONDER,
+				\SAML2\Constants::STATUS_NO_SUPPORTED_IDP,
+				$exception->getMessage(),
+				$exception
+			);
 		} else {
 			$e = new self(
 				\SAML2\Constants::STATUS_RESPONDER,
diff --git a/modules/saml/www/proxy/invalid_session.php b/modules/saml/www/proxy/invalid_session.php
index ac38a65d7aa83e783b9d0e571e400daefcd486d0..5369ace8a3bc68a0f92c6b1396fe3802397f7db2 100644
--- a/modules/saml/www/proxy/invalid_session.php
+++ b/modules/saml/www/proxy/invalid_session.php
@@ -28,8 +28,8 @@ try {
 
 if (isset($_POST['cancel'])) {
     // the user does not want to logout, cancel login
-    $e = new SimpleSAML_Error_Exception('User refused to reauthenticate with any of the IdPs requested.');
-    sspmod_saml_IdP_SAML2::handleAuthError($e, $state);
+    $e = new \SimpleSAML\Error\NoAvailableIDP('User refused to reauthenticate with any of the IdPs requested.');
+    SimpleSAML_Auth_State::throwException($state, $e);
 }
 
 if (isset($_POST['continue'])) {