> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gcore.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Video Lifecycle and Statuses

> Video lifecycle and statuses explained, from empty and pending through viewable and ready, with rendition progress and error handling.

Playback can start while a video is still transcoding. The status moves from `empty` to `pending`, then to `viewable` once one rendition is complete, and to `ready` when every rendition is complete. A processing failure sets the status to `error`, while an upload or source-check failure can leave the status at `empty` and put the cause in the `error` field.

## Video status

The `status` field on the video object reports that progress. The master playlist returns HTTP 404 until the video is `viewable` or `ready`.

```
Empty -> Pending -> Viewable -> Ready
```

| Status | Manifest HTTP status | Description |
| - | - | - |
| `Empty` | `404` | Video entity created, but no source file has been uploaded yet. For prolonged delays, inspect the error field |
| `Pending` | `404` | Source file uploaded and queued for processing. Transcoding is queued or already started. No final file is available yet, so the manifest returns 404 |
| `Viewable` | `200` | Playback available already. At least one rendition is available for playback, but not all target renditions are complete |
| `Ready` | `200` | Playback in all qualities. All renditions and codecs have been processed and are available for playback |
| `Error` | `404` | Processing failed. Details are in the `error` field |

> [!NOTE]
>
> Playback is available at `viewable`, including when only some renditions are complete. Further renditions are added to `master.m3u8` and `master.mpd` as processing finishes. The status becomes `ready` when every rendition is available.

A response while processing is still in progress:

```json theme={null}
{
  "id": 1001,
  "name": "Gcore Demo",
  "description": "Video copied from an external S3 Storage",
  "status": "pending",
  "screenshots": [],
  "origin_url": "https://demo-files.gvideo.io/gcore.mp4",
  "converted_videos": [
    {
      "name": "vod480n",
      "progress": 0,
      "status": "processing",
      "error": ""
    }
  ]
}
```

If the upload or the source check fails, the video stays `empty` and `error` explains why. A non-video file or a dropped connection is the usual cause. Re-upload from the origin, or delete the entity and create it again with a video file.

```json theme={null}
{
  "id": 1002,
  "name": "Gcore Demo",
  "description": "Video copied from an external S3 Storage",
  "status": "empty",
  "error": "File Invalid",
  "origin_url": "https://demo-files.gvideo.io/hls/master.m3u8",
  "converted_videos": []
}
```

A TUS upload or a copy from an external `origin_url` creates the video through the request in [API upload](/streaming/video-hosting/upload-video-via-api). The backend schedules transcodes for the target quality set, and each rendition becomes an item in `converted_videos`.

## Rendition status

Each video is transcoded into several qualities. Each quality is a rendition, and `converted_videos` lists them with playback metadata and a processing status.

* `processing`: the transcode job is accepted and running for this quality.
* `complete`: the rendition is finished. `mp4_url` is available and the quality is added to the HLS and DASH manifests.
* `error`: the rendition failed. The item `error` string gives the reason.

A rendition at `complete` is what makes the video `viewable`. Later renditions appear in the manifests as they finish.

The [Get video](/api-reference/streaming/videos/get-video#response-converted-videos) response lists width, height, size, `progress` from 0 to 100, `status`, `mp4_url` when the file exists, `error` on failure, and the quality `name`.

Transcoder workers report each rendition. The API maps those reports to `processing`, `complete`, or `error` on `converted_videos` in GET `/streaming/videos/{video_id}`. Completion events are also delivered through [VOD webhooks](/streaming/extra-features/get-webhooks-from-the-streaming-platform#webhooks-for-vod).

## Processing time

Transcoding time grows with the length of the source. A 1 minute video can be processed in seconds, while a 10 hour video can take tens of minutes. Other videos ahead in the queue can add further delay.

All renditions are queued together. Lower qualities finish sooner, so SD and other medium resolutions often become available before 1080, 2K, and 4K.

## Error handling

During upload and processing, `error` on the video object or on `converted_videos[i].error` explains why the file could not be fetched, parsed, or processed.

If a video stays `empty` or `pending` for a long time, read `error` and the `converted_videos[].status` values. The source often does not match the [input parameters](/streaming/live-streams-and-videos-protocols-and-codecs/input-parameters-and-codecs).

Match the message to the table, then check the URL, headers, and source file and retry. If the failure is a quota limit, contact support.

The transcoder expects pixel format, color range, and codec parameters to stay stable for the whole file. A source that changes from `yuv420p` to `yuvj420p` in the middle can stay in `error` after a retry. Re-export the file with stable parameters, or trim the broken segment and upload the corrected file.

| Error message | Description |
| - | - |
| Encoding problems | |
| Encoding has failed | Transcoding stopped due to broken or corrupted frames or unstable source parameters inside the file. Confirm the source file is playable and technically consistent for its full duration |
| Unable to analyze the origin file | File structure could not be parsed. Confirm the input format |
| Unable to validate video file | File validation failed. Confirm the input format |
| Video file has codec parameters issue | Codec parameters are unsupported or changed inside the file. Keep codec, pixel format, and color range stable throughout the full source |
| Video file has empty streams | No video streams detected in the file. Validate the content before upload |
| Video file is invalid | The file is not a recognized format or container. Verify the input format |
| Clips | |
| Requested encoding duration exceeds clip length | Requested clip duration exceeds the actual file duration. Review the start and end range |
| Limits | |
| The storage limit has been exceeded | Storage or encoding quota exceeded. Contact support to increase the limits |
| Migration from external origin | |
| Access to the origin is forbidden | `origin_url` requires authentication but failed. Check the URL and `origin_http_headers` |
| Connection reset by peer | `origin_url` exists but the external server dropped the connection |
| Network timeout occurred | `origin_url` exists but the external server did not respond |
| The downloaded file is incomplete | The file download started but finished incomplete. Validate the URL and the source server |
| The requested origin was not found | `origin_url` points to a non-existent HTTP resource. Verify the URL |

A `viewable` video can still carry an `error` on one rendition. The [Viewable demo](#viewable-demo) plays that case, and [VOD issues](/streaming/faq/vod-issues) lists the same failures in the portal.

## Viewable demo

A public demo stays at `viewable` because one quality was left in error on purpose.

[https://player.gvideo.co/videos/2675\_vGcX1W3aTFEL](https://player.gvideo.co/videos/2675_vGcX1W3aTFEL)

The player plays the video, and the completed files can be downloaded. The rendition `vod1080p` failed because storage space was limited, and its status is `error`.

* Entity status: `viewable`
* Renditions:
  * vod360p: `complete`
  * vod480p: `complete`
  * vod720p: `complete`
  * vod1080p: `error`

`master.m3u8` lists only the three completed renditions:

```
curl https://demo-public.gvideo.io/videos/2675_vGcX1W3aTFEL/master.m3u8

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1800000,RESOLUTION=720x1280,FRAME-RATE=23.980,CODECS="avc1.64001f",VIDEO-RANGE=SDR
index-s0q3570v1-v1.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=468x832,FRAME-RATE=23.980,CODECS="avc1.4d401e",VIDEO-RANGE=SDR
index-s0q3573v1-v1.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=450000,RESOLUTION=360x640,FRAME-RATE=23.980,CODECS="avc1.42c01e",VIDEO-RANGE=SDR
index-s0q3576v1-v1.m3u8

#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=130266,RESOLUTION=720x1280,CODECS="avc1.64001f",URI="iframes-s0q3570v1-v1.m3u8",VIDEO-RANGE=SDR
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=71689,RESOLUTION=468x832,CODECS="avc1.4d401e",URI="iframes-s0q3573v1-v1.m3u8",VIDEO-RANGE=SDR
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=43082,RESOLUTION=360x640,CODECS="avc1.42c01e",URI="iframes-s0q3576v1-v1.m3u8",VIDEO-RANGE=SDR
```
