Realizar subidas reanudables

Descripción general

En esta página se describe cómo hacer una solicitud de subida reanudable en las APIs JSON y XML de Cloud Storage. Este protocolo te permite reanudar una operación de subida después de que un error de comunicación interrumpa el flujo de datos.

Para obtener información sobre cómo usar las subidas reanudables en la CLI de Google Cloud y en las bibliotecas de cliente, consulta Cómo usan las herramientas y las APIs las subidas reanudables.

Roles obligatorios

Para obtener los permisos que necesitas para realizar una subida reanudable, pide a tu administrador que te asigne uno de los siguientes roles:

  • En el caso de las subidas que incluyan un bloqueo de conservación de objetos, pide a tu administrador que te conceda el rol de gestión de identidades y accesos Administrador de objetos de Storage (roles/storage.objectAdmin) para el segmento.

  • En el resto de los casos, pide a tu administrador que te conceda el rol de gestión de identidades y accesos Usuario de objetos de Storage (roles/storage.objectUser) para el segmento.

Estos roles predefinidos contienen los permisos necesarios para subir un objeto a un segmento en sus respectivos casos. Para ver los permisos exactos que se necesitan, despliega la sección Permisos necesarios:

Permisos obligatorios

  • storage.objects.create
  • storage.objects.delete
    • Este permiso solo es necesario para las subidas que sobrescriben un objeto.
  • storage.objects.setRetention
    • Este permiso solo es necesario para las subidas que incluyan un bloqueo de retención de objetos.

También puedes obtener estos permisos con otros roles predefinidos o roles personalizados.

Para obtener información sobre cómo conceder roles en los contenedores, consulta Usar IAM con contenedores.

Iniciar una sesión de subida reanudable

Para iniciar una sesión de subida reanudable, sigue estos pasos:

API JSON

  1. Tener instalada e inicializadala CLI de gcloud, que te permite generar un token de acceso para el encabezado Authorization.

  2. Opcionalmente, crea un archivo JSON que contenga los metadatos que quieras definir en el objeto que vas a subir. Por ejemplo, el siguiente archivo JSON define los metadatos contentType del objeto que quieres subir a image/png:

    {
        "contentType": "image/png"
    }
  3. Usa cURL para llamar a la API JSON con una solicitud de POST Object:

    curl -i -X POST --data-binary @METADATA_LOCATION \
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "Content-Length: INITIAL_REQUEST_LENGTH" \
        "https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME"

    Donde:

    • METADATA_LOCATION es la ruta local al archivo JSON que contiene los metadatos opcionales que has especificado en el paso anterior. Si no vas a incluir un archivo de metadatos, exclúyelo junto con --data-binary @ y el encabezado Content-Type.
    • INITIAL_REQUEST_LENGTH es el número de bytes del cuerpo de esta solicitud inicial. Por ejemplo, 79.
    • BUCKET_NAME es el nombre del segmento al que subes el objeto. Por ejemplo, my-bucket.
    • OBJECT_NAME es el nombre codificado en URL que quieres dar al objeto. Por ejemplo, pets/dog.png, codificada como URL pets%2Fdog.png. No es necesario si has incluido un name en el archivo de metadatos del objeto en el paso 2.

    Si has habilitado Uso compartido de recursos entre dominios, también debes incluir un encabezado Origin en esta solicitud y en las siguientes.

    Entre los encabezados opcionales que puedes añadir a la solicitud se incluyen X-Upload-Content-Type y X-Upload-Content-Length.

    Si la solicitud se completa correctamente, la respuesta incluye el código de estado 200 y tiene un aspecto similar al siguiente:

    HTTP/2 200
    content-type: text/plain; charset=utf-8
    x-guploader-uploadid: ABgVH8_jqDHM_KOvNAJCx73r9v5fINktk9U-pXana1szCM5803tlJ7CKsRbDxkyYCrfEiNqzcZ6B7DfoDtc-bdzpH-SpVTAMEO9EQV34qG0-0yk
    location: https://storage.googleapis.com/upload/storage/v1/b/my-bucket/o?uploadType=resumable&name=cat-pic.jpeg&upload_id=ABgVH8_jqDHM_KOvNAJCx73r9v5fINktk9U-pXana1szCM5803tlJ7CKsRbDxkyYCrfEiNqzcZ6B7DfoDtc-bdzpH-SpVTAMEO9EQV34qG0-0yk
    date: Mon, 07 Jul 2025 14:57:21 GMT
    vary: Origin
    vary: X-Origin
    cache-control: no-cache, no-store, max-age=0, must-revalidate
    expires: Mon, 01 Jan 1990 00:00:00 GMT
    pragma: no-cache
    content-length: 0
    server: UploadServer
    alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
  4. Guarda el URI de sesión reanudable que se indica en el encabezado location de la respuesta a tu solicitud de objeto POST.

    Este URI se usa en solicitudes posteriores para subir los datos del objeto.

API XML

  1. Tener instalada e inicializadala CLI de gcloud, que te permite generar un token de acceso para el encabezado Authorization.

  2. Usa cURL para llamar a la API XML con una solicitud de POST Object que tenga un cuerpo vacío:

    curl -i -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Length: 0" \
        -H "Content-Type: OBJECT_CONTENT_TYPE" \
        -H "x-goog-resumable: start" \
        "https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME"

    Donde:

    • OBJECT_CONTENT_TYPE es el tipo de contenido del objeto. Por ejemplo, image/png. Si no especifica un tipo de contenido, el sistema de Cloud Storage asigna el valor application/octet-stream a los metadatos Content-Type del objeto.
    • BUCKET_NAME es el nombre del segmento al que vas a subir el objeto. Por ejemplo, my-bucket.
    • OBJECT_NAME es el nombre codificado en URL que quieres dar al objeto. Por ejemplo, pets/dog.png, codificada como URL pets%2Fdog.png.

    Si has habilitado Uso compartido de recursos entre dominios, también debes incluir un encabezado Origin en esta solicitud y en las siguientes.

    Si la solicitud se completa correctamente, la respuesta incluye un mensaje de estado 201.

  3. Guarda el URI de sesión reanudable que se indica en el encabezado location de la respuesta a tu solicitud de objeto POST.

    Este URI se usa en solicitudes posteriores para subir los datos del objeto.

Subir los datos

Una vez que hayas iniciado una subida reanudable, hay dos formas de subir los datos del objeto:

  • En un solo fragmento: este enfoque suele ser el mejor, ya que requiere menos solicitudes y, por lo tanto, tiene un mejor rendimiento.
  • En varios fragmentos: utiliza este método si necesitas reducir la cantidad de datos transferidos en una sola solicitud, por ejemplo, si hay un límite de tiempo fijo para las solicitudes individuales o si no sabes el tamaño total de la subida en el momento en que empieza.

Subida de un solo fragmento

Para subir los datos en un solo bloque, sigue estos pasos:

API JSON

  1. Usa cURL para llamar a la API JSON con una solicitud de PUT objeto:

    curl -i -X PUT --data-binary @OBJECT_LOCATION \
        -H "Content-Length: OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • OBJECT_LOCATION es la ruta local a tu objeto. Por ejemplo, Desktop/dog.png.
    • OBJECT_SIZE es el número de bytes de tu objeto. Por ejemplo, 20000000.
    • SESSION_URI es el valor devuelto en el encabezado location cuando iniciaste la subida reanudable.

    También puedes incluir encabezados con el prefijo X-Goog-Meta- para añadir metadatos personalizados al objeto como parte de esta solicitud.

API XML

  1. Usa cURL para llamar a la API XML con una solicitud de objeto PUT:

    curl -i -X PUT --data-binary @OBJECT_LOCATION \
        -H "Content-Length: OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • OBJECT_LOCATION es la ruta local a tu objeto. Por ejemplo, Desktop/dog.png.
    • OBJECT_SIZE es el número de bytes de tu objeto. Por ejemplo, 20000000.
    • SESSION_URI es el valor devuelto en el encabezado Location cuando iniciaste la subida reanudable.

Si la subida se completa, recibirás una respuesta 200 OK o 201 Created, junto con los metadatos asociados al recurso.

Si se interrumpe la solicitud de subida o recibes una 5xx respuesta, sigue el procedimiento que se describe en Reanudar una subida interrumpida.

Subida de varios fragmentos

Para subir los datos en varios fragmentos, sigue estos pasos:

API JSON

  1. Crea un fragmento de datos a partir de los datos generales que quieras subir.

    El tamaño del fragmento debe ser un múltiplo de 256 KiB (256 x 1024 bytes), a menos que sea el último fragmento que complete la subida. Los tamaños de fragmento más grandes suelen acelerar las subidas, pero ten en cuenta que hay un equilibrio entre la velocidad y el uso de memoria. Se recomienda usar al menos 8 MiB para el tamaño del fragmento.

  2. Usa cURL para llamar a la API JSON con una solicitud de PUT objeto:

    curl -i -X PUT --data-binary @CHUNK_LOCATION \
        -H "Content-Length: CHUNK_SIZE" \
        -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • CHUNK_LOCATION es la ruta local al fragmento que estás subiendo.
    • CHUNK_SIZE es el número de bytes que estás subiendo en la solicitud actual. Por ejemplo, 8388608.
    • CHUNK_FIRST_BYTE es el byte de inicio del objeto general que contiene el fragmento que estás subiendo.
    • CHUNK_LAST_BYTE es el byte final del objeto general que contiene el fragmento que estás subiendo.
    • TOTAL_OBJECT_SIZE es el tamaño total del objeto que estás subiendo. Si no conoce el tamaño completo del objeto, utilice * para este valor.
    • SESSION_URI es el valor devuelto en el encabezado Location cuando iniciaste la subida reanudable.

    Un ejemplo de Content-Range es Content-Range: bytes 0-8388607/20000000. Consulta más información sobre este encabezado en Content-Range.

    Si la solicitud se realiza correctamente, el servidor responde con 308 Resume Incomplete. La respuesta contiene un encabezado Range.

  3. Repite los pasos anteriores con cada uno de los fragmentos de datos que quieras subir. Para determinar dónde empieza cada fragmento sucesivo, usa el valor superior incluido en el encabezado Range de cada respuesta. No supongas que el servidor ha recibido todos los bytes enviados en una solicitud determinada.

    Opcionalmente, en la solicitud final de la subida reanudable, puedes incluir encabezados con el prefijo X-Goog-Meta- para añadir metadatos personalizados al objeto.

API XML

  1. Crea un fragmento de datos a partir de los datos generales que quieras subir.

    El tamaño del fragmento debe ser un múltiplo de 256 KiB (256 x 1024 bytes), a menos que sea el último fragmento que complete la subida. Los tamaños de fragmento más grandes suelen acelerar las subidas, pero ten en cuenta que hay un equilibrio entre la velocidad y el uso de memoria. Se recomienda usar al menos 8 MiB para el tamaño del fragmento.

  2. Usa cURL para llamar a la API XML con una solicitud de objeto PUT:

    curl -i -X PUT --data-binary @CHUNK_LOCATION \
        -H "Content-Length: CHUNK_SIZE" \
        -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • CHUNK_LOCATION es la ruta local al fragmento que estás subiendo.
    • CHUNK_SIZE es el número de bytes que estás subiendo en la solicitud actual. Por ejemplo, 8388608.
    • CHUNK_FIRST_BYTE es el byte de inicio del objeto general que contiene el fragmento que estás subiendo.
    • CHUNK_LAST_BYTE es el byte final del objeto general que contiene el fragmento que estás subiendo.
    • TOTAL_OBJECT_SIZE es el tamaño total del objeto que estás subiendo. Si no conoce el tamaño completo del objeto, utilice * para este valor.
    • SESSION_URI es el valor devuelto en el encabezado Location cuando iniciaste la subida reanudable.

    Un ejemplo de Content-Range es Content-Range: bytes 0-8388607/20000000. Consulta más información sobre este encabezado en Content-Range.

    Si la solicitud se realiza correctamente, el servidor responde con 308 Resume Incomplete. La respuesta contiene un encabezado Range.

  3. Repite los pasos anteriores con cada uno de los fragmentos de datos que quieras subir. Para determinar dónde empieza cada fragmento sucesivo, usa el valor superior incluido en el encabezado Range de cada respuesta. No supongas que el servidor ha recibido todos los bytes enviados en una solicitud determinada.

Una vez que se haya completado la subida, recibirás una respuesta 200 OK o 201 Created, junto con los metadatos asociados al recurso.

Si se interrumpe alguna de las subidas de fragmentos o recibes una respuesta 5xx , debes volver a enviar el fragmento interrumpido por completo o reanudar la subida interrumpida en el punto en el que se interrumpió.

Consultar el estado de una subida reanudable

Si se interrumpe la subida reanudable o no sabes si se ha completado, puedes comprobar su estado:

API JSON

  1. Usa cURL para llamar a la API JSON con una solicitud de PUT objeto:

    curl -i -X PUT \
        -H "Content-Length: 0" \
        -H "Content-Range: bytes */OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • OBJECT_SIZE es el número total de bytes de tu objeto. Si no conoce el tamaño completo del objeto, utilice * para este valor.
    • SESSION_URI es el valor devuelto en el encabezado Location cuando iniciaste la subida reanudable.

API XML

  1. Usa cURL para llamar a la API XML con una solicitud de objeto PUT:

    curl -i -X PUT \
        -H "Content-Length: 0" \
        -H "Content-Range: bytes */OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • OBJECT_SIZE es el número total de bytes de tu objeto. Si no conoce el tamaño completo del objeto, utilice * para este valor.
    • SESSION_URI es el valor devuelto en el encabezado Location cuando iniciaste la subida reanudable.

Una respuesta 200 OK o 201 Created indica que la subida se ha completado y que no es necesario hacer nada más.

Una respuesta 308 Resume Incomplete indica que debes seguir subiendo los datos.

  • Si Cloud Storage aún no ha conservado ningún byte, la respuesta 308 no tiene un encabezado Range. En ese caso, debes empezar la subida desde el principio.
  • De lo contrario, la respuesta 308 tiene un encabezado Range, que especifica los bytes que Cloud Storage ha conservado hasta el momento. Utilice este valor cuando reanude una subida interrumpida.

Reanudar una subida interrumpida

Si una solicitud de subida se termina antes de recibir una respuesta o si recibes una respuesta 503 o 500, debes reanudar la subida interrumpida desde donde se quedó. Para reanudar una subida interrumpida, sigue estos pasos:

API JSON

  1. Consulta el estado de tu subida reanudable.

  2. Guarda el valor superior del encabezado Range incluido en la respuesta a la comprobación de estado. Si la respuesta no tiene un encabezado Range, significa que Cloud Storage aún no ha conservado ningún byte y debes subir desde el principio.

  3. Asegúrate de que los datos del objeto que vas a subir empiezan en el byte que sigue al valor superior del encabezado Range.

  4. Si la solicitud interrumpida contenía encabezados con el prefijo X-Goog-Meta-, inclúyelos en la solicitud para reanudar la subida.

  5. Usa cURL para llamar a la API JSON con una solicitud de PUT objeto que se inicia en el byte que sigue al valor del encabezado Range:

    curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \
        -H "Content-Length: UPLOAD_SIZE_REMAINING" \
        -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • PARTIAL_OBJECT_LOCATION es la ruta local a la parte restante de los datos que quieres subir.
    • UPLOAD_SIZE_REMAINING es el número de bytes que estás subiendo en la solicitud actual. Por ejemplo, si se sube el resto de un objeto con un tamaño total de 20.000.000 que se ha interrumpido después de subir los bytes del 0 al 42, el valor de UPLOAD_SIZE_REMAINING sería 19999957.
    • NEXT_BYTE es el siguiente número entero después del valor que has guardado en el paso 2. Por ejemplo, si 42 es el valor superior del paso 2, el valor de NEXT_BYTE es 43.
    • LAST_BYTE es el byte final incluido en esta solicitud PUT. Por ejemplo, para terminar de subir un objeto cuyo tamaño total es 20000000, el valor de LAST_BYTE es 19999999.
    • TOTAL_OBJECT_SIZE es el tamaño total del objeto que estás subiendo. Por ejemplo, 20000000. Si no conoce el tamaño completo del objeto, utilice * para este valor.
    • SESSION_URI es el valor devuelto en el encabezado Location cuando iniciaste la subida reanudable.

API XML

  1. Consulta el estado de tu subida reanudable.

  2. Guarda el valor superior del encabezado Range incluido en la respuesta a la comprobación de estado. Si la respuesta no tiene un encabezado Range , Cloud Storage aún no ha conservado ningún byte y debes subir desde el principio.

  3. Asegúrate de que los datos del objeto que vas a subir empiezan en el byte que sigue al valor superior del encabezado Range.

  4. Usa cURL para llamar a la API XML con un objeto PUT que recoja el byte que sigue al valor del encabezado Range:

    curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \
        -H "Content-Length: UPLOAD_SIZE_REMAINING" \
        -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • PARTIAL_OBJECT_LOCATION es la ruta local a la parte restante de los datos que quieres subir.
    • UPLOAD_SIZE_REMAINING es el número de bytes que estás subiendo en la solicitud actual. Por ejemplo, si se sube el resto de un objeto con un tamaño total de 20.000.000 que se ha interrumpido después de subir los bytes del 0 al 42, el valor de UPLOAD_SIZE_REMAINING sería 19999957.
    • NEXT_BYTE es el siguiente número entero después del valor que has guardado en el paso 2. Por ejemplo, si 42 es el valor superior del paso 2, el valor de NEXT_BYTE es 43.
    • LAST_BYTE es el byte final incluido en esta solicitud PUT. Por ejemplo, para terminar de subir un objeto cuyo tamaño total es 20000000, el valor de LAST_BYTE es 19999999.
    • TOTAL_OBJECT_SIZE es el tamaño total del objeto que estás subiendo. Por ejemplo, 20000000. Si no sabes el tamaño completo del objeto, usa * para este valor.
    • SESSION_URI es el valor devuelto en el encabezado Location cuando iniciaste la subida reanudable.

Puedes reanudar las subidas tantas veces como sea necesario mientras el URI de sesión esté activo. El URI de sesión caduca al cabo de una semana. Cuando los datos se suben correctamente, Cloud Storage responde con un código de estado 200 OK o 201 created.

Cancelar una subida

Para cancelar una subida reanudable incompleta e impedir que se realice ninguna otra acción en ella, sigue estos pasos:

API JSON

  1. Usa cURL para llamar a la API JSON con una DELETE solicitud:

    curl -i -X DELETE -H "Content-Length: 0" \
      "SESSION_URI"

    Donde:

Si la solicitud se completa correctamente, la respuesta contiene el código de estado 499. Los intentos posteriores de consultar o reanudar la subida darán como resultado una respuesta 4xx.

API XML

  1. Usa cURL para llamar a la API XML con una DELETE solicitud:

    curl -i -X DELETE -H "Content-Length: 0" \
      "SESSION_URI"

    Donde:

Si la solicitud se completa correctamente, la respuesta contiene el código de estado 204 y los futuros intentos de consultar o reanudar la subida también darán como resultado una respuesta 204.

Gestión de errores

En raras ocasiones, es posible que no se pueda reanudar una subida interrumpida y se produzca un error "4xx" no reintentable porque han cambiado los permisos del segmento o porque la comprobación de integridad del objeto subido final ha detectado una discrepancia. Si esto ocurre, vuelve a intentar la subida iniciando una nueva sesión de subida reanudable.

Siguientes pasos