diff --git a/lib/SimpleSAML/Session.php b/lib/SimpleSAML/Session.php
index fd847cb03de6f15156974a7cd86623ed38f0a3ea..5c7a13bcf2fee477b58638da3a0303ea68a96a50 100644
--- a/lib/SimpleSAML/Session.php
+++ b/lib/SimpleSAML/Session.php
@@ -453,6 +453,9 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function save()
     {
+        // clean out old data
+        $this->expireData();
+
         if (!$this->dirty) {
             // session hasn't changed, don't bother saving it
             return;
@@ -894,9 +897,6 @@ class Session implements \Serializable, Utils\ClearableState
         assert(is_string($id));
         assert(is_int($timeout) || $timeout === null || $timeout === self::DATA_TIMEOUT_SESSION_END);
 
-        // clean out old data
-        $this->expireData();
-
         if ($timeout === null) {
             // use the default timeout
             $timeout = self::$config->getInteger('session.datastore.timeout', null);
@@ -952,6 +952,7 @@ class Session implements \Serializable, Utils\ClearableState
 
                 if ($ct > $info['expires']) {
                     unset($typedData[$id]);
+                    $this->markDirty();
                 }
             }
         }
@@ -977,8 +978,6 @@ class Session implements \Serializable, Utils\ClearableState
             return null;
         }
 
-        $this->expireData();
-
         if (!array_key_exists($type, $this->dataStore)) {
             return null;
         }