spurious stats
diff --git a/quiche/src/lib.rs b/quiche/src/lib.rs
index 88ce158..cfac381 100644
--- a/quiche/src/lib.rs
+++ b/quiche/src/lib.rs
@@ -1185,6 +1185,7 @@
 
     /// Total number of lost packets.
     lost_count: usize,
+    spurious_count: usize,
 
     /// Total number of packets sent with data retransmitted.
     retrans_count: usize,
@@ -1664,6 +1665,7 @@
             recv_count: 0,
             sent_count: 0,
             lost_count: 0,
+            spurious_count: 0,
             retrans_count: 0,
             sent_bytes: 0,
             recv_bytes: 0,
@@ -5805,6 +5807,7 @@
             recv: self.recv_count,
             sent: self.sent_count,
             lost: self.lost_count,
+            spurious: self.spurious_count,
             retrans: self.retrans_count,
             sent_bytes: self.sent_bytes,
             recv_bytes: self.recv_bytes,
@@ -6185,7 +6188,7 @@
                         p.recovery.delivery_rate_update_app_limited(true);
                     }
 
-                    let (lost_packets, lost_bytes) = p.recovery.on_ack_received(
+                    let (lost_packets, lost_bytes, spurious_packets) = p.recovery.on_ack_received(
                         &ranges,
                         ack_delay,
                         epoch,
@@ -6196,6 +6199,7 @@
 
                     self.lost_count += lost_packets;
                     self.lost_bytes += lost_bytes as u64;
+                    self.spurious_count += spurious_packets
                 }
 
                 if self.handshake_confirmed {
@@ -6989,6 +6993,7 @@
 
     /// The number of QUIC packets that were lost.
     pub lost: usize,
+    pub spurious: usize,
 
     /// The number of sent QUIC packets with retransmitted data.
     pub retrans: usize,
@@ -7053,8 +7058,8 @@
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         write!(
             f,
-            "recv={} sent={} lost={} retrans={}",
-            self.recv, self.sent, self.lost, self.retrans,
+            "recv={} sent={} lost={} retrans={} spurious={}",
+            self.recv, self.sent, self.lost, self.retrans, self.spurious,
         )?;
 
         write!(
diff --git a/quiche/src/recovery/mod.rs b/quiche/src/recovery/mod.rs
index 120d6bb..ad257f2 100644
--- a/quiche/src/recovery/mod.rs
+++ b/quiche/src/recovery/mod.rs
@@ -416,7 +416,7 @@
         &mut self, ranges: &ranges::RangeSet, ack_delay: u64,
         epoch: packet::Epoch, handshake_status: HandshakeStatus, now: Instant,
         trace_id: &str,
-    ) -> Result<(usize, usize)> {
+    ) -> Result<(usize, usize, usize)> {
         let largest_acked = ranges.last().unwrap();
 
         // While quiche used to consider ACK frames acknowledging packet numbers
@@ -444,6 +444,8 @@
 
         let max_rtt = cmp::max(self.latest_rtt, self.rtt());
 
+        let lost_spurious_count_prev = self.lost_spurious_count;
+
         // Detect and mark acked packets, without removing them from the sent
         // packets list.
         for r in ranges.iter() {
@@ -532,8 +534,10 @@
             (self.cc_ops.rollback)(self);
         }
 
+        let lost_spurious_packets = self.lost_spurious_count - lost_spurious_count_prev;
+
         if newly_acked.is_empty() {
-            return Ok((0, 0));
+            return Ok((0, 0, lost_spurious_packets));
         }
 
         if largest_newly_acked_pkt_num == largest_acked && has_ack_eliciting {
@@ -567,7 +571,7 @@
 
         self.drain_packets(epoch, now);
 
-        Ok((lost_packets, lost_bytes))
+        Ok((lost_packets, lost_bytes, lost_spurious_packets))
     }
 
     pub fn on_loss_detection_timeout(