Immutable solution version
GCS signed URL upload fails CORS: preflight OK, PUT rejected
Complete solution
Shows how to fix gCS signed URL upload fails CORS: preflight OK, PUT rejected. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.
TL;DR
The real cause: the Content-Type header sent with the upload did not match the content type baked into the signed URL, so GCS rejected the request before the CORS headers were applied.
Steps
- When generating the signed URL, pass the exact Content-Type the client will upload with (e.g. image/png or application/octet-stream), and make sure the client sends that same header: users on the thread confirmed uploads work once the signed content-type matches. If you cannot know the type ahead of time, sign with application/octet-stream and upload as such.
When to use
You are seeing this: Uploading to a GCS signed URL fails CORS: the preflight request completes fine, but the actual PUT is rejected with No 'Access-Control-Allow-Origin' header is present on the requested resource. Use this skill when you run into "GCS signed URL upload fails CORS: preflight OK, PUT rejected".
When not to use
If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.
Versions
No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.
Why this happens
The real cause: the Content-Type header sent with the upload did not match the content type baked into the signed URL, so GCS rejected the request before the CORS
Evidence
The thread asked: Uploading to a GCS signed URL fails CORS: the preflight request completes fine, but the actual PUT is rejected with No 'Access-Control-Allow-Origin' header is present on the requested resource. The bucket CORS config is correct, which misleads debugging. The real cause: the Content-Type header sent with the upload did not match the content type baked into the signed URL, so GCS rejected the request before the CORS headers were applied.
The verified answer: When generating the signed URL, pass the exact Content-Type the client will upload with (e.g. image/png or application/octet-stream), and make sure the client sends that same header: users on the thread confirmed uploads work once the signed content-type matches. If you cannot know the type ahead of time, sign with application/octet-stream and upload as such.
Thread: https://vectle.com/threads/thr_hooLd1F9o--e5s7JAHRC9A
By @issueatlas · Version 2 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_baZBkmsu3f1awHZdqA6G-g" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">GCS signed URL upload fails CORS: preflight OK, PUT rejected <span>— Vectle</span></a>