diff --git a/app/lib/dal/indexDAL/leveldb/LevelDBCindex.ts b/app/lib/dal/indexDAL/leveldb/LevelDBCindex.ts
index 8dfab34d878214c6be200dcbc9b775559bcd8702..0777ffe412241f47d4d23aa349987f9a3d6b8d37 100644
--- a/app/lib/dal/indexDAL/leveldb/LevelDBCindex.ts
+++ b/app/lib/dal/indexDAL/leveldb/LevelDBCindex.ts
@@ -96,7 +96,10 @@ export class LevelDBCindex extends LevelDBTable<LevelDBCindexEntry> implements C
         .filter(f => f.expired_on && f.writtenOn < belowNumber)
         .forEach(f => {
           maxExpired = Math.max(maxExpired, f.expired_on)
-          toRemove.push(LevelDBCindex.trimFullKey(f.issuer, f.receiver, f.created_on))
+          // We must remove **all** the remaining entries for this issuer + receiver
+          entry.issued
+            .filter(e => e.issuer === f.issuer && e.receiver === f.receiver)
+            .forEach(e => toRemove.push(LevelDBCindex.trimFullKey(e.issuer, e.receiver, e.created_on)))
         })
       if (toRemove.length) {
         // Trim the expired certs that won't be rolled back ever
diff --git a/test/integration/certification/certification-expiry.ts b/test/integration/certification/certification-expiry.ts
new file mode 100644
index 0000000000000000000000000000000000000000..518d1af28107dce614e9346bcd584451d2424250
--- /dev/null
+++ b/test/integration/certification/certification-expiry.ts
@@ -0,0 +1,105 @@
+// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1
+// Copyright (C) 2018  Cedric Moreau <cem.moreau@gmail.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+
+import {assertEqual, writeBasicTestWithConfAnd2Users} from "../tools/test-framework"
+
+describe('Certification expiry + trimming', () => writeBasicTestWithConfAnd2Users({
+  sigReplay: 3,
+  sigPeriod: 0,
+  sigValidity: 10,
+}, (test) => {
+
+  const now = 1500000000
+
+  test('should be able to init with 2 blocks', async (s1, cat, tac, toc) => {
+    await cat.createIdentity()
+    await tac.createIdentity()
+    await toc.createIdentity()
+    // Circular certs
+    await cat.cert(tac)
+    await tac.cert(toc)
+    await toc.cert(cat)
+    await cat.join()
+    await tac.join()
+    await toc.join()
+    await s1.commit({ time: now, version: 10 })
+    await s1.commit({ time: now })
+    // Circular WoT
+    assertEqual(s1._server.dal.wotb.dumpWoT(), `[M] [E] [R] [I] -> Links[maxCert = 40]
+[0] [1] [1] [1] -> 2 | 
+[1] [1] [1] [1] -> 0 | 
+[2] [1] [1] [1] -> 1 | 
+`)
+  })
+
+  test('some replays from tac at t+4 and t+6', async (s1, cat, tac, toc) => {
+    await s1.commit({ time: now + 4 })
+    await s1.commit({ time: now + 4 }) // <-- it is now t+4
+    await tac.cert(toc)
+    await s1.commit({ time: now + 6 })
+    await s1.commit({ time: now + 6 }) // <-- it is now t+6
+    await tac.cert(cat)
+    await s1.commit({ time: now + 8 })
+    // Wot adds a certificat for tac to cat
+    assertEqual(s1._server.dal.wotb.dumpWoT(), `[M] [E] [R] [I] -> Links[maxCert = 40]
+[0] [1] [2] [1] -> 2 | 1 | 
+[1] [1] [1] [2] -> 0 | 
+[2] [1] [1] [1] -> 1 | 
+`)
+  })
+
+  test('also, toc certify cat and tac later to keep the wot safe', async (s1, cat, tac, toc) => {
+    await s1.commit({ time: now + 8 }) // <-- it is now t+8
+    await toc.cert(cat)
+    await s1.commit({ time: now + 9 })
+    await s1.commit({ time: now + 9 }) // <-- it is now t+9
+    await toc.cert(tac)
+    await s1.commit({ time: now + 9 })
+    assertEqual(s1._server.dal.wotb.dumpWoT(), `[M] [E] [R] [I] -> Links[maxCert = 40]
+[0] [1] [2] [1] -> 2 | 1 | 
+[1] [1] [2] [2] -> 0 | 2 | 
+[2] [1] [1] [2] -> 1 | 
+`)
+  })
+
+  test('at t+10, only cat -> tac cert should be removed (it has not been replayed)', async (s1) => {
+    await s1.commit({ time: now + 10 }) // Change `Time`
+    await s1.commit({ time: now + 10 }) // <-- it is now t+10
+    assertEqual(s1._server.dal.wotb.dumpWoT(), `[M] [E] [R] [I] -> Links[maxCert = 40]
+[0] [1] [2] [0] -> 2 | 1 | 
+[1] [1] [1] [2] -> 2 | 
+[2] [1] [1] [2] -> 1 | 
+`)
+  })
+
+  test('at t+14, tac -> toc cert should be removed', async (s1) => {
+    await s1.commit({ time: now + 14 }) // Change `Time`
+    await s1.commit({ time: now + 14 }) // Change `MedianTime`
+    assertEqual(s1._server.dal.wotb.dumpWoT(), `[M] [E] [R] [I] -> Links[maxCert = 40]
+[0] [1] [2] [0] -> 2 | 1 | 
+[1] [1] [1] [1] -> 2 | 
+[2] [1] [0] [2] -> 
+`)
+  })
+
+  test('at t+16, tac -> cat cert should be removed without bug', async (s1) => {
+    await s1._server.dal.cindexDAL.trimExpiredCerts(16) // <-- **THIS** is what was triggering the core dump
+    await s1.commit({ time: now + 16 }) // Change `Time`
+    await s1.commit({ time: now + 16 }) // Change `MedianTime`
+    assertEqual(s1._server.dal.wotb.dumpWoT(), `[M] [E] [R] [I] -> Links[maxCert = 40]
+[0] [1] [1] [0] -> 2 | 
+[1] [1] [1] [0] -> 2 | 
+[2] [0] [0] [2] -> 
+`)
+  })
+}))