diff --git a/src/api/encryption.c b/src/api/encryption.c
index e576c3deceb48079aff4db30c1bf8a0a77404e1e..0951f062d436a953816231e6ad18c1c842132fd8 100644
--- a/src/api/encryption.c
+++ b/src/api/encryption.c
@@ -13,16 +13,53 @@
 int callback_encryption(const struct _u_request * request,
     struct _u_response * response, void * user_data)
 {
-    char * encryption_status;
+    bool encrypted;
+    bool * can_encrypt_nullable = NULL;
+    bool can_encrypt = true;
+    json_t * messages = json_array();
+
     if (path_exists(DATA_PARTITION_DEVICE) &&
         is_encrypted_device(DATA_PARTITION_DEVICE))
     {
-        encryption_status = "encrypted";
+        encrypted = true;
     }
     else
     {
-        encryption_status = "unencrypted";
+        encrypted = false;
+        can_encrypt_nullable = &can_encrypt;
+
+        // Mount the filesystem on the unencrypted device.
+        int r = temporary_mount(ROOT_DEVICE, UNENCRYPTED_MOUNTPOINT,
+            FILESYSTEM_TYPE);
+        if (r != 0)
+        {
+            printf("mounting root device failed: return code %d\n", r);
+            return send_simple_response(response, 500, "error",
+               "mounting root device failed");
+        }
+        bool fits = filesystem_fits_in_memory(UNENCRYPTED_MOUNTPOINT,
+            MEMORY_USAGE, true);
+        umount(UNENCRYPTED_MOUNTPOINT);
+        if (! fits)
+        {
+            can_encrypt = false;
+            json_array_append_new(messages, json_string(
+                "existing files do not fit in memory"));
+        }
     }
-    return send_simple_response(response, 200,
-        "encryption-status", encryption_status);
+
+    json_t * json_body = NULL;
+    json_body = json_object();
+
+    json_object_set_new(json_body, "encrypted",
+        encrypted ? json_true() : json_false());
+
+    json_object_set_new(json_body, "can-encrypt",
+        can_encrypt_nullable == NULL ? json_null() :
+            (can_encrypt ? json_true() : json_false()));
+    json_object_set_new(json_body, "messages", messages);
+
+    ulfius_set_json_body_response(response, 200, json_body);
+    json_decref(json_body);
+    return U_CALLBACK_CONTINUE;
 }
diff --git a/src/api/encryption_init.c b/src/api/encryption_init.c
index f708cd0d5e1cfc7d1282ebe01f8085eea74ee606..92d1d0ff861dfd3bcf49f378b817c4426f46b4fc 100644
--- a/src/api/encryption_init.c
+++ b/src/api/encryption_init.c
@@ -63,22 +63,9 @@ int callback_encryption_init(const struct _u_request * request,
     }
 
     // Determine the filesystem usage of the device to be encrypted.
-    unsigned long size = filesystem_usage(UNENCRYPTED_MOUNTPOINT);
-    if (size < 0)
-    {
-        // Something went wrong in determining the filesystem usage.
-        printf("determining filesystem usage failed: return code %lu\n", size);
-        return send_simple_response(response, 500, "error",
-           "determining filesystem usage failed");
-    }
-    printf("root device usage: %lu bytes\n", size);
-
-    // Determine the available memory.
-    unsigned long memory = available_memory();
-
-    double projected_usage = (double)size / (double)memory;
-    printf("projected memory usage: %.3f\n", projected_usage);
-    if (projected_usage > MEMORY_USAGE)
+    bool fits = filesystem_fits_in_memory(UNENCRYPTED_MOUNTPOINT,
+        MEMORY_USAGE, true);
+    if (! fits)
     {
         // Projected memory usage is really high, so abort.
         return send_simple_response(response, 500, "error",
diff --git a/src/auxiliary.c b/src/auxiliary.c
index 6b833d80adc22a36440437496bb7fc0936e4ebb1..9773c09528bd10ef5120a9bb745b9fc733a5981e 100644
--- a/src/auxiliary.c
+++ b/src/auxiliary.c
@@ -111,6 +111,45 @@ unsigned long filesystem_usage(const char * path)
     return (s.f_blocks - s.f_bfree) * s.f_bsize;
 }
 
+/**
+ * Check if the files on the given filesystem would fit into memory.
+ * @param  path          Path of the mounted filesystem.
+ * @param  safety_margin Fraction (between zero and one) of free memory to
+                         deem available for containing the files.
+ * @param  debug         Whether to print debug messages.
+ * @return               Whether the filesystem seems to fit into memory.
+ */
+bool filesystem_fits_in_memory(const char * path, double safety_margin,
+    bool debug)
+{
+    // Determine the filesystem usage of the device to be encrypted.
+    unsigned long size = filesystem_usage(path);
+    if (size < 0)
+    {
+        // Something went wrong in determining the filesystem usage.
+        // Return false as a precaution.
+        if (debug)
+        {
+            printf("Determining file system usage failed (size: %lu)\n", size);
+        }
+        return false;
+    }
+    if (debug)
+    {
+        printf("file system usage: %lu bytes\n", size);
+    }
+
+    // Determine the available memory.
+    unsigned long memory = available_memory();
+
+    double projected_usage = (double)size / (double)memory;
+    if (debug)
+    {
+        printf("projected memory usage: %.3f\n", projected_usage);
+    }
+    return (projected_usage <= safety_margin);
+}
+
 /**
  * Mount a filesystem; create the mount target if it doesn't exist.
  * @param  device_path Path to the device to mount.