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
Tener instalada e inicializadala CLI de gcloud, que te permite generar un token de acceso para el encabezado
Authorization
.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 aimage/png
:{ "contentType": "image/png" }
Usa
cURL
para llamar a la API JSON con una solicitud dePOST
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 encabezadoContent-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 URLpets%2Fdog.png
. No es necesario si has incluido unname
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
yX-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
Guarda el URI de sesión reanudable que se indica en el encabezado
location
de la respuesta a tu solicitud de objetoPOST
.Este URI se usa en solicitudes posteriores para subir los datos del objeto.
API XML
Tener instalada e inicializadala CLI de gcloud, que te permite generar un token de acceso para el encabezado
Authorization
.Usa
cURL
para llamar a la API XML con una solicitud dePOST
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 valorapplication/octet-stream
a los metadatosContent-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 URLpets%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
.Guarda el URI de sesión reanudable que se indica en el encabezado
location
de la respuesta a tu solicitud de objetoPOST
.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
Usa
cURL
para llamar a la API JSON con una solicitud dePUT
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 encabezadolocation
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
Usa
cURL
para llamar a la API XML con una solicitud de objetoPUT
: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 encabezadoLocation
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
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.
Usa
cURL
para llamar a la API JSON con una solicitud dePUT
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 encabezadoLocation
cuando iniciaste la subida reanudable.
Un ejemplo de
Content-Range
esContent-Range: bytes 0-8388607/20000000
. Consulta más información sobre este encabezado enContent-Range
.Si la solicitud se realiza correctamente, el servidor responde con
308 Resume Incomplete
. La respuesta contiene un encabezadoRange
.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
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.
Usa
cURL
para llamar a la API XML con una solicitud de objetoPUT
: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 encabezadoLocation
cuando iniciaste la subida reanudable.
Un ejemplo de
Content-Range
esContent-Range: bytes 0-8388607/20000000
. Consulta más información sobre este encabezado enContent-Range
.Si la solicitud se realiza correctamente, el servidor responde con
308 Resume Incomplete
. La respuesta contiene un encabezadoRange
.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
Usa
cURL
para llamar a la API JSON con una solicitud dePUT
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 encabezadoLocation
cuando iniciaste la subida reanudable.
API XML
Usa
cURL
para llamar a la API XML con una solicitud de objetoPUT
: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 encabezadoLocation
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 encabezadoRange
. En ese caso, debes empezar la subida desde el principio. - De lo contrario, la respuesta
308
tiene un encabezadoRange
, 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
Consulta el estado de tu subida reanudable.
Guarda el valor superior del encabezado
Range
incluido en la respuesta a la comprobación de estado. Si la respuesta no tiene un encabezadoRange
, significa que Cloud Storage aún no ha conservado ningún byte y debes subir desde el principio.Asegúrate de que los datos del objeto que vas a subir empiezan en el byte que sigue al valor superior del encabezado
Range
.Si la solicitud interrumpida contenía encabezados con el prefijo
X-Goog-Meta-
, inclúyelos en la solicitud para reanudar la subida.Usa
cURL
para llamar a la API JSON con una solicitud dePUT
objeto que se inicia en el byte que sigue al valor del encabezadoRange
: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 deUPLOAD_SIZE_REMAINING
sería19999957
.NEXT_BYTE
es el siguiente número entero después del valor que has guardado en el paso 2. Por ejemplo, si42
es el valor superior del paso 2, el valor deNEXT_BYTE
es43
.LAST_BYTE
es el byte final incluido en esta solicitudPUT
. Por ejemplo, para terminar de subir un objeto cuyo tamaño total es20000000
, el valor deLAST_BYTE
es19999999
.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 encabezadoLocation
cuando iniciaste la subida reanudable.
API XML
Consulta el estado de tu subida reanudable.
Guarda el valor superior del encabezado
Range
incluido en la respuesta a la comprobación de estado. Si la respuesta no tiene un encabezadoRange
, Cloud Storage aún no ha conservado ningún byte y debes subir desde el principio.Asegúrate de que los datos del objeto que vas a subir empiezan en el byte que sigue al valor superior del encabezado
Range
.Usa
cURL
para llamar a la API XML con un objetoPUT
que recoja el byte que sigue al valor del encabezadoRange
: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 deUPLOAD_SIZE_REMAINING
sería19999957
.NEXT_BYTE
es el siguiente número entero después del valor que has guardado en el paso 2. Por ejemplo, si42
es el valor superior del paso 2, el valor deNEXT_BYTE
es43
.LAST_BYTE
es el byte final incluido en esta solicitudPUT
. Por ejemplo, para terminar de subir un objeto cuyo tamaño total es20000000
, el valor deLAST_BYTE
es19999999
.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 encabezadoLocation
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
Usa
cURL
para llamar a la API JSON con unaDELETE
solicitud:curl -i -X DELETE -H "Content-Length: 0" \ "SESSION_URI"
Donde:
SESSION_URI
es el valor devuelto en el encabezadoLocation
cuando iniciaste la subida reanudable.
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
Usa
cURL
para llamar a la API XML con unaDELETE
solicitud:curl -i -X DELETE -H "Content-Length: 0" \ "SESSION_URI"
Donde:
SESSION_URI
es el valor devuelto en el encabezadoLocation
cuando iniciaste la subida reanudable.
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
- Más información sobre las subidas reanudables
- Consulta una descripción general de la API JSON y la API XML.
- Subidas de flujo de tamaño desconocido.
- Envía varias solicitudes a la API JSON de Cloud Storage por lotes.