diff --git a/modules/saml/www/sp/saml2-acs.php b/modules/saml/www/sp/saml2-acs.php
index e0e93415cdbb8bb162461b7774db81ac995adc35..611ea0b08bde3fa615b4e1976cd4abd9d203bf03 100644
--- a/modules/saml/www/sp/saml2-acs.php
+++ b/modules/saml/www/sp/saml2-acs.php
@@ -186,23 +186,42 @@ if ($expire !== null) {
     $logoutExpire = time() + 24 * 60 * 60;
 }
 
-// register this session in the logout store
-sspmod_saml_SP_LogoutStore::addSession($sourceId, $nameId, $sessionIndex, $logoutExpire);
-
-// we need to save the NameID and SessionIndex for logout
-$logoutState = array(
-    'saml:logout:Type'         => 'saml2',
-    'saml:logout:IdP'          => $idp,
-    'saml:logout:NameID'       => $nameId,
-    'saml:logout:SessionIndex' => $sessionIndex,
-);
+if (!empty($nameId)) {
+    // register this session in the logout store
+    sspmod_saml_SP_LogoutStore::addSession($sourceId, $nameId, $sessionIndex, $logoutExpire);
+
+    // we need to save the NameID and SessionIndex for logout
+    $logoutState = array(
+        'saml:logout:Type'         => 'saml2',
+        'saml:logout:IdP'          => $idp,
+        'saml:logout:NameID'       => $nameId,
+        'saml:logout:SessionIndex' => $sessionIndex,
+    );
+
+    $state['saml:sp:NameID'] = $nameId; // no need to mark it as persistent, it already is
+} else {
+    /*
+     * No NameID provided, we can't logout from this IdP!
+     *
+     * Even though interoperability profiles "require" a NameID, the SAML 2.0 standard does not require it to be present
+     * in assertions. That way, we could have a Subject with only a SubjectConfirmation, or even no Subject element at
+     * all.
+     *
+     * In case we receive a SAML assertion with no NameID, we can be graceful and continue, but we won't be able to
+     * perform a Single Logout since the SAML logout profile mandates the use of a NameID to identify the individual we
+     * want to be logged out. In order to minimize the impact of this, we keep logout state information (without saving
+     * it to the store), marking the IdP as SAML 1.0, which does not implement logout. Then we can safely log the user
+     * out from the local session, skipping Single Logout upstream to the IdP.
+     */
+    $logoutState = array(
+        'saml:logout:Type'         => 'saml1',
+    );
+}
+
 $state['LogoutState'] = $logoutState;
 $state['saml:AuthenticatingAuthority'] = $authenticatingAuthority;
 $state['saml:AuthenticatingAuthority'][] = $idp;
 $state['PersistentAuthData'][] = 'saml:AuthenticatingAuthority';
-
-$state['saml:sp:NameID'] = $nameId;
-$state['PersistentAuthData'][] = 'saml:sp:NameID';
 $state['saml:sp:SessionIndex'] = $sessionIndex;
 $state['PersistentAuthData'][] = 'saml:sp:SessionIndex';
 $state['saml:sp:AuthnContext'] = $assertion->getAuthnContext();