Index: src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
===================================================================
--- src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php	(revision 48524)
+++ src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php	(working copy)
@@ -484,37 +484,9 @@
 			);
 		}
 
-		if ( 0 !== $rotate ) {
-			$result = $image_editor->rotate( $rotate );
+		// Create the attachment post now. This will allow retrying of the image post-processing
+		// if the server is busy at the moment.
 
-			if ( is_wp_error( $result ) ) {
-				return new WP_Error(
-					'rest_image_rotation_failed',
-					__( 'Unable to rotate this image.' ),
-					array( 'status' => 500 )
-				);
-			}
-		}
-
-		if ( $crop ) {
-			$size = $image_editor->get_size();
-
-			$crop_x = round( ( $size['width'] * floatval( $request['x'] ) ) / 100.0 );
-			$crop_y = round( ( $size['height'] * floatval( $request['y'] ) ) / 100.0 );
-			$width  = round( ( $size['width'] * floatval( $request['width'] ) ) / 100.0 );
-			$height = round( ( $size['height'] * floatval( $request['height'] ) ) / 100.0 );
-
-			$result = $image_editor->crop( $crop_x, $crop_y, $width, $height );
-
-			if ( is_wp_error( $result ) ) {
-				return new WP_Error(
-					'rest_image_crop_failed',
-					__( 'Unable to crop this image.' ),
-					array( 'status' => 500 )
-				);
-			}
-		}
-
 		// Calculate the file name.
 		$image_ext  = pathinfo( $image_file, PATHINFO_EXTENSION );
 		$image_name = wp_basename( $image_file, ".{$image_ext}" );
@@ -537,16 +509,9 @@
 		// Make the file name unique in the (new) upload directory.
 		$filename = wp_unique_filename( $uploads['path'], $filename );
 
-		// Save to disk.
-		$saved = $image_editor->save( $uploads['path'] . "/$filename" );
-
-		if ( is_wp_error( $saved ) ) {
-			return $saved;
-		}
-
 		// Create new attachment post.
 		$new_attachment_post = array(
-			'post_mime_type' => $saved['mime-type'],
+			'post_mime_type' => $mime_type,
 			'guid'           => $uploads['url'] . "/$filename",
 			'post_title'     => $image_name,
 			'post_content'   => '',
@@ -581,6 +546,61 @@
 			update_post_meta( $new_attachment_id, '_wp_attachment_image_alt', wp_slash( $image_alt ) );
 		}
 
+		if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
+			// Set a custom header with the attachment_id.
+			// Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
+			header( 'X-WP-Upload-Attachment-ID: ' . $new_attachment_id );
+		}
+
+		// Edit the image.
+		if ( 0 !== $rotate ) {
+			$result = $image_editor->rotate( $rotate );
+
+			if ( is_wp_error( $result ) ) {
+				return new WP_Error(
+					'rest_image_rotation_failed',
+					__( 'Unable to rotate this image.' ),
+					array( 'status' => 500 )
+				);
+			}
+		}
+
+		if ( $crop ) {
+			$size = $image_editor->get_size();
+
+			$crop_x = round( ( $size['width'] * floatval( $request['x'] ) ) / 100.0 );
+			$crop_y = round( ( $size['height'] * floatval( $request['y'] ) ) / 100.0 );
+			$width  = round( ( $size['width'] * floatval( $request['width'] ) ) / 100.0 );
+			$height = round( ( $size['height'] * floatval( $request['height'] ) ) / 100.0 );
+
+			$result = $image_editor->crop( $crop_x, $crop_y, $width, $height );
+
+			if ( is_wp_error( $result ) ) {
+				return new WP_Error(
+					'rest_image_crop_failed',
+					__( 'Unable to crop this image.' ),
+					array( 'status' => 500 )
+				);
+			}
+		}
+
+		// Save to disk.
+		$saved = $image_editor->save( $uploads['path'] . "/$filename" );
+
+		if ( is_wp_error( $saved ) ) {
+			return $saved;
+		}
+
+		// Ensure the new attachment mime type matches the image mime type as returned by $image_editor->save().
+		if ( $mime_type !== $saved['mime-type'] ) {
+			wp_update_post(
+				array(
+					'ID'             => $new_attachment_id,
+					'post_mime_type' => $saved['mime-type'],
+				)
+			);
+		}
+
 		// Generate image sub-sizes and meta.
 		$new_image_meta = wp_generate_attachment_metadata( $new_attachment_id, $saved['path'] );
 
