Skip to content

WASM S3 PUT signs a Content-Type it never sends → 403 SignatureDoesNotMatch (regression of #105 via #234) #351

Description

@konstantinoscs

Summary

When using DuckDB-Wasm, any S3 data-file write (COPY (...) TO 's3://...', or an Iceberg INSERT/CREATE TABLE) fails with 403 SignatureDoesNotMatch on the PUT. Reads with the same credentials work. SignatureDoesNotMatch is returned at S3's auth step before any policy eval, so this is purely request-signing — not creds/IAM/CORS/region.

I am building a web app that uses duckDB wasm to attach to a Polaris catalog backed by S3 and while reads work fine, I get the following error on writes:

Image

Root cause

I've already root caused this: s3fs.cpp::CreateS3Header signs content-type:application/octet-stream into the canonical request + SignedHeaders for every PUT, but the != "application/octet-stream" guard suppresses emitting it. Native curl/httplib re-add the default (signed==sent); WASM's http_wasm.cc::HTTPWasmClient::Put sends a Uint8Array body via sync XHR with the setRequestHeader("Content-Type", …) lines commented out → per the XHR spec, no Content-Type on the wire. Signed application/octet-stream vs. sent nothing ⇒ 403.

I did some tracking in the issue and interestingly it was solved and then reborken — #101 added the emission (broke native) → #105 #ifdef EMSCRIPTEN-guarded it (WASM worked; @samansmink: "Won't this still break things on wasm?") → #234 replaced the guard with != "application/octet-stream", silently re-breaking WASM. No open issue tracks this.

Reproduction

minimal COPY (SELECT 1) TO 's3://…' on duckdb-wasm ≥ v1.30.0 → 403; DevTools shows the canonical request signing content-type:application/octet-stream with no Content-Type sent.

Proposed fix

emit the signed Content-Type under EMSCRIPTEN, native unchanged (the s3fs.cpp diff). Restores #105 for WASM, keeps #234's native behavior. PR to follow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions