diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # ChangeLog
 
+## 0.2.12
+
+* Dont' send UDP packets of size 0. (Cloudfare)
+* Retransmitted NewConnectionID does not reach the limit. (AdGuard)
+
 ## 0.2.11
 
 * `ConnectionIsClosed` now takes reason.
diff --git a/Network/QUIC/Connection/Migration.hs b/Network/QUIC/Connection/Migration.hs
--- a/Network/QUIC/Connection/Migration.hs
+++ b/Network/QUIC/Connection/Migration.hs
@@ -94,14 +94,15 @@
     let lim = activeConnectionIdLimit $ getMyParameters conn
     atomically $ do
         db <- readTVar peerCIDDB
-        let n = Map.size $ revInfos db
-        if n >= lim
-            then return False
-            else do
-                case Map.lookup (cidInfoCID cidInfo) (revInfos db) of
-                    Nothing -> modifyTVar' peerCIDDB $ add cidInfo
-                    Just _ -> return ()
-                return True
+        case Map.lookup (cidInfoCID cidInfo) (revInfos db) of
+            Nothing -> do
+                let n = Map.size $ revInfos db
+                if n >= lim
+                    then return False
+                    else do
+                        modifyTVar' peerCIDDB $ add cidInfo
+                        return True
+            Just _ -> return True -- maybe retransmitted
 
 shouldUpdatePeerCID :: Connection -> IO Bool
 shouldUpdatePeerCID Connection{..} =
diff --git a/Network/QUIC/Sender.hs b/Network/QUIC/Sender.hs
--- a/Network/QUIC/Sender.hs
+++ b/Network/QUIC/Sender.hs
@@ -60,14 +60,17 @@
                 pathInfo <- getPathInfo conn
                 when (isServer conn) $
                     waitAntiAmplificationFree conn pathInfo bytes
-                now <- getTimeMicrosecond
-                connSend conn buf0 bytes
-                addTxBytes conn bytes
-                addPathTxBytes pathInfo bytes
-                forM_ sentPackets $ \sentPacket0 -> do
-                    let sentPacket = sentPacket0{spTimeSent = now}
-                    qlogSent conn sentPacket now
-                    onPacketSent ldcc sentPacket
+                -- If the secret of this level (e.g. HandshakeLevel)
+                -- is already dropped, bytes is 0.
+                when (bytes > 0) $ do
+                    now <- getTimeMicrosecond
+                    connSend conn buf0 bytes
+                    addTxBytes conn bytes
+                    addPathTxBytes pathInfo bytes
+                    forM_ sentPackets $ \sentPacket0 -> do
+                        let sentPacket = sentPacket0{spTimeSent = now}
+                        qlogSent conn sentPacket now
+                        onPacketSent ldcc sentPacket
     buildPackets _ _ _ [] _ = error "sendPacket: buildPackets"
     buildPackets buf bufsiz siz [spkt] build0 = do
         let pkt = spPlainPacket spkt
@@ -120,7 +123,7 @@
                     ping = spPlainPacket spkt
                 let sizbuf@(SizedBuffer buf _) = encryptRes conn
                 (bytes, padlen) <- encodePlainPacket conn sizbuf ping (Just maxSiz)
-                when (bytes >= 0) $ do
+                when (bytes > 0) $ do
                     now <- getTimeMicrosecond
                     connSend conn buf bytes
                     addTxBytes conn bytes
diff --git a/quic.cabal b/quic.cabal
--- a/quic.cabal
+++ b/quic.cabal
@@ -1,6 +1,6 @@
 cabal-version:      >=1.10
 name:               quic
-version:            0.2.11
+version:            0.2.12
 license:            BSD3
 license-file:       LICENSE
 maintainer:         kazu@iij.ad.jp
