Skip to content

400 Bad Request after POST using pre-signed URL generated by gcloud CLI #2254

Description

@samneisewander

Problem

When performing a POST request on a pre-signed URL to initiate a resumable upload, the server responds with 400 Bad Request (an equivalent request made to GCS is successful).

To reproduce, generate a pre-signed URL using the gcloud CLI:

gcloud storage sign-url gs://test-bucket/test-object --http-verb=POST --headers=x-goog-resumable=start,content-type=application/octet-stream --impersonate-service-account=[ACCOUNT] --region=us-east4

Then POST using the resulting URL:

curl -i -X POST "http://test-bucket.localhost:4443/test-object?x-goog-signature=[SIGNATURE]&x-goog-algorithm=GOOG4-RSA-SHA256&x-goog-credential=[CREDENTIAL]&x-goog-date=[DATE]&x-goog-expires=3600&x-goog-signedheaders=content-type%3Bhost%3Bx-goog-resumable" \
  -H "x-goog-resumable: start" \
  -H "Content-Type: application/octet-stream"

Response is

HTTP/1.1 400 Bad Request
Content-Type: application/json
Date: Fri, 26 Jun 2026 14:13:27 GMT
Content-Length: 139

{"error":{"code":400,"message":"invalid uploadType","errors":[{"domain":"global","reason":"Bad Request","message":"invalid uploadType"}]}}

Expected Behavior

The server should return 200 OK or 201 Created along with a sessionURI, mimiking the behavior of the actual API: resumable upload response example

i.e. follow the same procedure as above an instead receive the response:

HTTP/1.1 200 OK
Content-Type: application/json
Location: http://test-bucket.localhost:4443/upload/storage/v1/b/test-bucket/o?uploadType=resumable&name=&upload_id=ee0eafdcd11110ea4d206ef84bcb23d1
Date: Fri, 26 Jun 2026 14:21:55 GMT
Content-Length: 481

{"kind":"storage#object","name":"","id":"test-bucket/","bucket":"test-bucket","size":"0","acl":[{"bucket":"test-bucket","entity":"projectOwner-test-project","etag":"RVRhZw==","kind":"storage#objectAccessControl","projectTeam":{},"role":"OWNER"}],"storageClass":"STANDARD","generation":"0","selfLink":"http://test-bucket.localhost:4443/storage/v1/b/test-bucket/o/","mediaLink":"http://test-bucket.localhost:4443/download/storage/v1/b/test-bucket/o/?alt=media","metageneration":"1"}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions