diff --git a/resources/FatMessages b/resources/FatMessages
index 912586674..12d81bd5e 100644
--- a/resources/FatMessages
+++ b/resources/FatMessages
@@ -119,6 +119,7 @@ nl.all.FrameDrag:frames aan het aanpassen
 # Units
 # =====
 #
+# Decimal prefix
 en.all.Bytes: B
 de.all.Bytes: B
 fr.all.Bytes: octets
@@ -139,7 +140,13 @@ de.all.GBytes: GB
 fr.all.GBytes: Go
 it.all.GBytes: GB
 nl.all.GBytes: GB
-
+# Binary prefix
+en.all.KiBytes: KiB
+en.all.MiBytes: MiB
+en.all.GiBytes: GiB
+en.all.TiBytes: TiB
+en.all.PiBytes: PiB
+en.all.EiBytes: EiB
 
 # Content Forms
 # =============
diff --git a/test/utils.c b/test/utils.c
index 3d5319a28..9fe6747c3 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -37,22 +37,31 @@
 #define SLEN(x) (sizeof((x)) - 1)
 
 struct test_pairs {
-	const unsigned long test;
+	const unsigned long long int test;
 	const char* res;
 };
 
 static const struct test_pairs human_friendly_bytesize_test_vec[] = {
-	{ 0, "0.00Bytes" },
-	{ 1024, "1024.00Bytes" },
-	{ 1025, "1.00kBytes" },
-	{ 1048576, "1024.00kBytes" },
-	{ 1048577, "1.00MBytes" },
-	{ 1073741824, "1024.00MBytes" },
-	{ 1073741888, "1024.00MBytes" }, /* spot the rounding error */
-	{ 1073741889, "1.00GBytes" },
-	{ 2147483648, "2.00GBytes" },
-	{ 3221225472, "3.00GBytes" },
-	{ 4294967295, "4.00GBytes" },
+	{                  0ULL,         "0Bytes" },
+	{               0x2AULL,        "42Bytes" },
+	{              0x400ULL,      "1024Bytes" },
+	{              0x401ULL,    "1.00KiBytes" },
+	{             0xA9AEULL,   "42.42KiBytes" },
+	{           0x100000ULL, "1024.00KiBytes" },
+	{           0x100001ULL,    "1.00MiBytes" },
+	{          0x2A6B852ULL,   "42.42MiBytes" },
+	{         0x40000000ULL, "1024.00MiBytes" },
+	{         0x40000001ULL,    "1.00GiBytes" },
+	{         0x80000000ULL,    "2.00GiBytes" },
+	{         0xC0000000ULL,    "3.00GiBytes" },
+	{        0x100000000ULL,    "4.00GiBytes" },
+	{      0x10000000000ULL, "1024.00GiBytes" },
+	{      0x10000000001ULL,    "1.00TiBytes" },
+	{    0x4000000000000ULL, "1024.00TiBytes" },
+	{    0x4000000000001ULL,    "1.00PiBytes" },
+	{ 0x1000000000000000ULL, "1024.00PiBytes" },
+	{ 0x1000000000000100ULL,    "1.00EiBytes" }, /* precision loss */
+	{ 0xFFFFFFFFFFFFFFFFULL,   "16.00EiBytes" },
 };
 
 /**
diff --git a/utils/string.h b/utils/string.h
index 03d891700..abb343154 100644
--- a/utils/string.h
+++ b/utils/string.h
@@ -64,7 +64,7 @@ char *cnv_space2nbsp(const char *s);
  * @param bytesize The size in bytes.
  * @return A human readable string representing the size.
  */
-char *human_friendly_bytesize(unsigned long bytesize);
+char *human_friendly_bytesize(unsigned long long int bytesize);
 
 
 /**
diff --git a/utils/utils.c b/utils/utils.c
index aec0116a0..c5c1529a3 100644
--- a/utils/utils.c
+++ b/utils/utils.c
@@ -192,26 +192,43 @@ nserror snstrjoin(char **str, size_t *size, char sep, size_t nelm, ...)
 /**
  * The size of buffers within human_friendly_bytesize.
  *
- * We can have a fairly good estimate of how long the buffer needs to
- * be.	The unsigned long can store a value representing a maximum
- * size of around 4 GB.  Therefore the greatest space required is to
- * represent 1023MB.  Currently that would be represented as "1023MB"
- * so 12 including a null terminator.  Ideally we would be able to
- * know this value for sure, in the mean time the following should
- * suffice.
+ * We can have a fairly good estimate of the output buffers maximum length.
+ *
+ * The unsigned long long int can store a value representing a maximum
+ *   size of 16 EiB (exibytes).  Therefore the greatest space required is to
+ *   represent 1023 PiB.
+ * Currently that would be represented as "1023.00PiBytes" in english
+ *   giving a 15 byte length including a null terminator.
+ * Ideally we would be able to accurately know this length for other
+ *   languages, in the mean time a largeish buffer size is selected
+ *   and should suffice.
  */
-#define BYTESIZE_BUFFER_SIZE 20
+#define BYTESIZE_BUFFER_SIZE 32
 
 /* exported interface documented in utils/string.h */
-char *human_friendly_bytesize(unsigned long bsize) {
+char *human_friendly_bytesize(unsigned long long int bsize) {
 	static char buffer1[BYTESIZE_BUFFER_SIZE];
 	static char buffer2[BYTESIZE_BUFFER_SIZE];
 	static char buffer3[BYTESIZE_BUFFER_SIZE];
 	static char *curbuffer = buffer3;
-	enum {bytes, kilobytes, megabytes, gigabytes} unit = bytes;
-	static char units[][7] = {"Bytes", "kBytes", "MBytes", "GBytes"};
-
-	float bytesize = (float)bsize;
+	enum {
+	      bytes,
+	      kilobytes,
+	      megabytes,
+	      gibibytes,
+	      tebibytes,
+	      pebibytes,
+	      exbibytes	} unit = bytes;
+	static const char *const units[] = {
+		"Bytes",
+		"KiBytes",
+		"MiBytes",
+		"GiBytes",
+		"TiBytes",
+		"PiBytes",
+		"EiBytes" };
+	double bytesize = (double)bsize;
+	const char *fmt;
 
 	if (curbuffer == buffer1)
 		curbuffer = buffer2;
@@ -232,10 +249,35 @@ char *human_friendly_bytesize(unsigned long bsize) {
 
 	if (bytesize > 1024) {
 		bytesize /= 1024;
-		unit = gigabytes;
+		unit = gibibytes;
 	}
 
-	snprintf(curbuffer, BYTESIZE_BUFFER_SIZE, "%3.2f%s", bytesize, messages_get(units[unit]));
+	if (bytesize > 1024) {
+		bytesize /= 1024;
+		unit = tebibytes;
+	}
+
+	if (bytesize > 1024) {
+		bytesize /= 1024;
+		unit = pebibytes;
+	}
+
+	if (bytesize > 1024) {
+		bytesize /= 1024;
+		unit = exbibytes;
+	}
+
+	if (unit == bytes) {
+		fmt = "%.0f%s";
+	} else {
+		fmt = "%3.2f%s";
+	}
+
+	snprintf(curbuffer,
+		 BYTESIZE_BUFFER_SIZE,
+		 fmt,
+		 bytesize,
+		 messages_get(units[unit]));
 
 	return curbuffer;
 }