diff --git a/image_creator/disk.py b/image_creator/disk.py
index 2191df3b4160aa64207be5b7b92e045dd0b3cbdb..3ff02692e709eadd3f7e2db50bb0509a0f679df1 100644
--- a/image_creator/disk.py
+++ b/image_creator/disk.py
@@ -320,6 +320,8 @@ class DiskDevice(object):
 
         self.out.output("Shrinking image (this may take a while)...", False)
 
+        sector_size = self.g.blockdev_getss(self.guestfs_device)
+
         last_part = None
         fstype = None
         while True:
@@ -336,7 +338,10 @@ class DiskDevice(object):
                 part_del(last_part['part_num'])
                 continue
 
-            self.meta['SIZE'] = last_part['part_end'] + 1
+            # Most disk manipulation programs leave 2048 sectors after the last
+            # partition
+            new_size = last_part['part_end'] + 1 + 2048 * sector_size
+            self.meta['SIZE'] = min(self.meta['SIZE'], new_size)
             break
 
         if not re.match("ext[234]", fstype):
@@ -353,7 +358,6 @@ class DiskDevice(object):
         block_cnt = int(
             filter(lambda x: x[0] == 'Block count', out)[0][1])
 
-        sector_size = self.g.blockdev_getss(self.guestfs_device)
         start = last_part['part_start'] / sector_size
         end = start + (block_size * block_cnt) / sector_size - 1
 
@@ -398,13 +402,18 @@ class DiskDevice(object):
                 part_set_id(last_part['part_num'], last_part['id'])
 
         new_size = (end + 1) * sector_size
-        self.out.success("new size is %dMB" % ((new_size + MB - 1) // MB))
+
+        assert (new_size <= self.meta['SIZE'])
 
         if self.meta['PARTITION_TABLE'] == 'gpt':
             ptable = GPTPartitionTable(self.real_device)
-            self.meta['SIZE'] = ptable.shrink(new_size)
+            self.meta['SIZE'] = ptable.shrink(new_size, self.meta['SIZE'])
         else:
-            self.meta['SIZE'] = new_size
+            self.meta['SIZE'] = min(new_size + 2048 * sector_size,
+                                    self.meta['SIZE'])
+
+        self.out.success("new size is %dMB" %
+                         ((self.meta['SIZE'] + MB - 1) // MB))
 
         return self.meta['SIZE']
 
diff --git a/image_creator/gpt.py b/image_creator/gpt.py
index f6f1cc29280755f9d1280ad5d0c400e9868aae4f..afc2f7a3220ec265f43cc1decf0c5b3370b701b0 100644
--- a/image_creator/gpt.py
+++ b/image_creator/gpt.py
@@ -255,18 +255,24 @@ class GPTPartitionTable(object):
         """Returns the payload size of GPT partitioned device."""
         return (self.primary.backup_lba + 1) * BLOCKSIZE
 
-    def shrink(self, size):
+    def shrink(self, size, old_size):
         """Move the secondary GPT Header entries to the address specified by
         size parameter.
         """
-        if size == self.size():
-            return size
 
-        assert size < self.size()
+        # Most partition manipulation programs leave 2048 sector after the last
+        # partition
+        aligned = size + 2048 * BLOCKSIZE
+
+        # new_size is at least: size + Partition Entries + Secondary GPT Header
+        new_size = aligned if aligned <= old_size else \
+                   size + len(self.part_entries) + BLOCKSIZE
+
+        assert new_size <= old_size, "The secodary GPT fits in the device"
+
+        if new_size == self.size():
+            return new_size
 
-        # new_size = size + Partition Entries + Secondary GPT Header
-        new_size = size + len(self.part_entries) + BLOCKSIZE
-        new_size = ((new_size + 4095) // 4096) * 4096  # align to 4K
         lba_count = new_size // BLOCKSIZE
 
         # Correct MBR