diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index 4ea87bea7ea3e71b61b2766b464e1a1acf2b24e3..ce2c4e30c73fee4bb955e61db704b3ae9cc07a24 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -157,12 +157,26 @@ def fetch(self):
             tty.msg("Already downloaded %s" % self.archive_file)
             return
 
+        possible_files = self.stage.expected_archive_files
+        save_file = None
+        partial_file = None
+        if possible_files:
+            save_file = self.stage.expected_archive_files[0]
+            partial_file = self.stage.expected_archive_files[0] + '.part'
+
         tty.msg("Trying to fetch from %s" % self.url)
 
-        curl_args = ['-O',  # save file to disk
+        if partial_file:
+            save_args = ['-C', '-',          # continue partial downloads
+                         '-o', partial_file] # use a .part file
+        else:
+            save_args = ['-O']
+
+        curl_args = save_args + [
                      '-f',  # fail on >400 errors
                      '-D', '-',  # print out HTML headers
-                     '-L', self.url, ]
+                     '-L',  # resolve 3xx redirects
+                     self.url, ]
 
         if sys.stdout.isatty():
             curl_args.append('-#')  # status bar when using a tty
@@ -178,6 +192,9 @@ def fetch(self):
             if self.archive_file:
                 os.remove(self.archive_file)
 
+            if partial_file and os.path.exists(partial_file):
+                os.remove(partial_file)
+
             if spack.curl.returncode == 22:
                 # This is a 404.  Curl will print the error.
                 raise FailedDownloadError(
@@ -209,6 +226,9 @@ def fetch(self):
                      "'spack clean <package>' to remove the bad archive, then fix",
                      "your internet gateway issue and install again.")
 
+        if save_file:
+            os.rename(partial_file, save_file)
+
         if not self.archive_file:
             raise FailedDownloadError(self.url)
 
diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py
index d711752c208f936d52a8e10c7799f6771f609c9f..84c47ee66026f8fe1befece987cd1dfaa3c68c3f 100644
--- a/lib/spack/spack/stage.py
+++ b/lib/spack/spack/stage.py
@@ -210,6 +210,18 @@ def _need_to_create_path(self):
 
         return False
 
+    @property
+    def expected_archive_files(self):
+        """Possible archive file paths."""
+        paths = []
+        if isinstance(self.fetcher, fs.URLFetchStrategy):
+            paths.append(os.path.join(self.path, os.path.basename(self.fetcher.url)))
+
+        if self.mirror_path:
+            paths.append(os.path.join(self.path, os.path.basename(self.mirror_path)))
+
+        return paths
+
     @property
     def archive_file(self):
         """Path to the source archive within this stage directory."""