diff --git a/apps/i2psnark/java/src/org/klomp/snark/Snark.java b/apps/i2psnark/java/src/org/klomp/snark/Snark.java
index ba62cf6274eda6ab8be34d9aa50c8418d9e0ab4a..c8fd37970818610133167005f9d62c7262f09c88 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Snark.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Snark.java
@@ -745,6 +745,18 @@ public class Snark
         return storage != null && storage.isChecking();
     }
 
+    /**
+     *  If checking is in progress, return completion 0-100,
+     *  else return 100.
+     *  @since 0.9.23
+     */
+    public double getCheckingProgress() {
+        if (storage != null && storage.isChecking())
+            return storage.getCheckingProgress();
+        else
+            return 100.0d;
+    }
+
     /**
      *  Disk allocation (ballooning) in progress.
      *  @since 0.9.3
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
index 6d73ed658697a1a657aaf4cf3228eb3c60ecbab5..7d80aa291a9ddc7443a6b5a3c1bf2d7ccc653e4e 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
@@ -73,6 +73,7 @@ public class Storage implements Closeable
   private boolean changed;
   private volatile boolean _isChecking;
   private final AtomicInteger _allocateCount = new AtomicInteger();
+  private final AtomicInteger _checkProgress = new AtomicInteger();
 
   /** The default piece size. */
   private static final int DEFAULT_PIECE_SIZE = 256*1024;
@@ -311,6 +312,18 @@ public class Storage implements Closeable
       return _isChecking;
   }
 
+  /**
+   *  If checking is in progress, return completion 0-100,
+   *  else return 100.
+   *  @since 0.9.23
+   */
+  public double getCheckingProgress() {
+      if (_isChecking)
+          return _checkProgress.get() / (double) pieces;
+      else
+          return 100.0d;
+  }
+
   /**
    *  Disk allocation (ballooning) in progress.
    *  Always false on Windows.
@@ -869,6 +882,7 @@ public class Storage implements Closeable
 
   private void locked_checkCreateFiles(boolean recheck) throws IOException
   {
+    _checkProgress.set(0);
     // Whether we are resuming or not,
     // if any of the files already exists we assume we are resuming.
     boolean resume = false;
@@ -885,13 +899,16 @@ public class Storage implements Closeable
 
     // Make sure all files are available and of correct length
     // The files should all exist as they have been created with zero length by createFilesFromNames()
+    long lengthProgress = 0;
     for (TorrentFile tf : _torrentFiles)
       {
         long length = tf.RAFfile.length();
+        lengthProgress += tf.length;
         if(tf.RAFfile.exists() && length == tf.length)
           {
             if (listener != null)
               listener.storageAllocated(this, length);
+            _checkProgress.set(0);
             resume = true; // XXX Could dynamicly check
           }
         else if (length == 0) {
@@ -903,6 +920,8 @@ public class Storage implements Closeable
                   tf.closeRAF();
               } catch (IOException ioe) {}
           }
+          if (!resume)
+              _checkProgress.set((int) (pieces * lengthProgress / total_length));
         } else {
           String msg = "File '" + tf.name + "' exists, but has wrong length (expected " +
                        tf.length + " but found " + length + ") - repairing corruption";
@@ -911,6 +930,7 @@ public class Storage implements Closeable
           _log.error(msg);
           changed = true;
           resume = true;
+          _checkProgress.set(0);
           _probablyComplete = false; // to force RW
           synchronized(tf) {
               RandomAccessFile raf = tf.checkRAF();
@@ -931,6 +951,7 @@ public class Storage implements Closeable
         long pieceEnd = 0;
         for (int i = 0; i < pieces; i++)
           {
+            _checkProgress.set(i);
             int length = getUncheckedPiece(i, piece);
             boolean correctHash = metainfo.checkPiece(i, piece, 0, length);
             // close as we go so we don't run out of file descriptors
@@ -957,6 +978,7 @@ public class Storage implements Closeable
           }
       }
 
+    _checkProgress.set(pieces);
     _probablyComplete = complete();
     // close all the files so we don't end up with a zillion open ones;
     // we will reopen as needed
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index 2368c7536f72d99078b7e008a8a5241a0755fcd7..f59ae0bdc9e7de6f255afb08000f5106600c0947 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -1471,7 +1471,8 @@ public class I2PSnarkServlet extends BasicServlet {
         String statusString;
         if (snark.isChecking()) {
             statusString = toThemeImg("stalled", "", _("Checking")) + "</td>" +
-                           "<td class=\"snarkTorrentStatus\">" + _("Checking");
+                           "<td class=\"snarkTorrentStatus\">" + _("Checking") + ' ' +
+                           (new DecimalFormat("0.00%")).format(snark.getCheckingProgress());
         } else if (snark.isAllocating()) {
             statusString = toThemeImg("stalled", "", _("Allocating")) + "</td>" +
                            "<td class=\"snarkTorrentStatus\">" + _("Allocating");
@@ -2924,8 +2925,9 @@ public class I2PSnarkServlet extends BasicServlet {
                 buf.append("<tr><td>");
                 toThemeImg(buf, "file");
                 if (snark.isChecking()) {
-                    buf.append("&nbsp;<b>").append(_("Checking")).append("&hellip;</b>&nbsp;&nbsp;&nbsp;")
-                       .append("<a href=\"").append(base).append("\">")
+                    buf.append("&nbsp;<b>").append(_("Checking")).append("&hellip; ")
+                       .append((new DecimalFormat("0.00%")).format(snark.getCheckingProgress()))
+                       .append("&nbsp;&nbsp;&nbsp;<a href=\"").append(base).append("\">")
                        .append(_("Refresh page for results")).append("</a>");
                 } else if (snark.isStarting()) {
                     buf.append("&nbsp;<b>").append(_("Starting")).append("&hellip;</b>");