# Import a disk image as a volume

Create a volume whose initial content is a disk image downloaded from an HTTP(S) URL, size it correctly, and check that the import succeeded.

Import a disk image when you’ve built one yourself and want it as a volume’s initial content. The platform downloads the image from an HTTP(S) URL, converts it to raw format, and writes it into a new volume. To launch instances from the result, snapshot and protect the volume, then create an image from the snapshot.

## Before you begin [#before-you-begin]

<BeforeYouBegin>

- The URN of the project to create the volume in.
- Permission `pvs.volume.create` on the project, the same permission as creating a volume. See [Roles](/docs/iam/roles).
- An active organization, a billing account that can pay, and enough volume storage quota for the full size you ask for. See [Create a volume](/docs/storage/volumes/create).
- A disk image at an HTTP(S) URL. The platform sends a plain GET request with no credentials, so the URL itself must grant access.
- The image’s virtual size. This is the size of the disk the image represents, not the size of the file you download. For a compressed or sparse image the file is much smaller. For a qcow2 image, `qemu-img info` shows it as `virtual size`.

</BeforeYouBegin>

## Choose the image and size [#choose-the-image-and-size]

The platform detects the image format and converts it. Common disk image formats are accepted, including qcow2 (also compressed qcow2) and raw. Host the image file itself, not an archive of it such as `.gz` or `.xz`.

`sizeInGib` is the size of the volume you get. It’s what the disk becomes, what counts against your quota, and what you’re billed for:

- An image whose virtual size is smaller than `sizeInGib` leaves you the extra space.
- An image whose virtual size is larger than `sizeInGib` is refused. The import fails and the volume ends in `ERROR`, because the platform can’t shrink your image without destroying part of it.

## Import the image [#import-the-image]

1. Start the import with a size of at least the image’s virtual size.

   ```sh
   origin storage import-volume --project-urn <project-urn> \
     --size-in-gib 20 \
     --source-url https://example.com/images/my-image.qcow2
   ```

   With the API, use the `importVolume` mutation:

   ```graphql
   mutation {
     pvs {
       importVolume(input: {
         projectUrn: "<project-urn>"
         sizeInGib: 20
         sourceUrl: "https://example.com/images/my-image.qcow2"
       }) {
         urn
         status
       }
     }
   }
   ```

   Add `--storage-class` or `storageClass` to choose a class other than the default. See [Storage classes](/docs/storage/volumes/storage-classes).

1. Check the volume’s status until it leaves `CREATING`.

   ```sh
   origin storage get-volume --volume-urn <volume-urn>
   ```

   `AVAILABLE` means the import succeeded and the volume holds your image.

## Time limits [#time-limits]

An import must finish within 25 minutes, including downloading, converting, and writing the image. The import fails with `ERR_IMPORT` when:

- it takes longer than 25 minutes, for example a very large image or a slow source,
- the source answers with an HTTP error status,
- the source sends no data for 60 seconds.

## If the import fails [#if-the-import-fails]

A failed import leaves the volume in `ERROR`, and `statusReason` names the cause:

| `statusReason` | Cause and fix |
| --- | --- |
| `the operation failed (ERR_IMPORT_IMAGE_TOO_LARGE)` | The image’s virtual size is larger than `sizeInGib`. Delete the volume and import again with a larger size. |
| `the operation failed (ERR_IMPORT)` | The download, conversion, or write failed, or the import ran out of time. Delete the volume and import again, from a faster source if time was the problem. |

No data from a failed import is kept, but the `ERROR` volume counts against your quota until you delete it. See [Delete a volume](/docs/storage/volumes/delete).

## Next steps [#next-steps]

- [Create and protect a snapshot](/docs/storage/snapshots/create-and-protect)
- [Create an image](/docs/compute/images/create)

## Related [#related]

- [Volume states](/docs/storage/volumes/volume-states)
- [`import-volume` command](/docs/storage/reference/cli#import-volume)

