Bug Report: SignatureDoesNotMatch error when opening PDFs with Japanese (multibyte) filenames on Cloudflare R2
Hi,
I've encountered a reproducible bug where uploaded PDF files become
inaccessible to paid members when the filename contains Japanese
(multibyte/Unicode) characters.
Environment
- FCOM Pro: 2.5.0
- WordPress: 6.9.4
- PHP: 8.3.30
- Media storage: Cloudflare R2
What happens
Opening a protected file returns a SignatureDoesNotMatch error from
Cloudflare R2 instead of displaying the PDF.
Reproduced pattern
Filename Result 日本語のファイル名.pdf (Japanese only) ❌ SignatureDoesNotMatch alphabet-日本語.pdf (ASCII + Japanese) ❌ SignatureDoesNotMatch alphabet-name.pdf (ASCII only) ✅ Works alphabet-name.zip (Japanese file zipped under ASCII name) ✅ WorksThe workaround of zipping files under ASCII names confirms the issue
is isolated to filename encoding, not file content or permissions.
Root cause hypothesis
The Presigned URL generation appears to incorrectly handle non-ASCII
characters when building the canonical request for AWS Signature V4
(used by Cloudflare R2). This causes a mismatch between the string
that was signed and the string in the actual request.
The error XML from R2 shows the Japanese characters were URL-encoded
in the CanonicalRequest (e.g. 詩 → %E8%A9%A9), suggesting a
double-encoding or inconsistent encoding issue between signing and
requesting.
Impact
Any paid content uploaded with a non-ASCII filename is completely
inaccessible to members. This is a significant issue for sites
serving non-Latin-script languages (Japanese, Chinese, Korean, Arabic,
etc.).
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your secret access key and signing method.</Message>
<StringToSign>AWS4-HMAC-SHA256 20260523T090708Z 20260523/us-east-1/s3/aws4_request 81159417291576cd5641cd08b05ba66d2ecbeefc77924d349ee410edb1ebdd19</StringToSign>
<StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 32 36 30 35 32 33 54 30 39 30 37 30 38 5a 0a 32 30 32 36 30 35 32 33 2f 75 73 2d 65 61 73 74 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 38 31 31 35 39 34 31 37 32 39 31 35 37 36 63 64 35 36 34 31 63 64 30 38 62 30 35 62 61 36 36 64 32 65 63 62 65 65 66 63 37 37 39 32 34 64 33 34 39 65 65 34 31 30 65 64 62 31 65 62 64 64 31 39</StringToSignBytes>
<CanonicalRequest>GET /community/fluentcom-oisxSpB7cK20UI1nXoDyO6KE4Ti53egW-fluentcom-upp-poetical-tractatus-%E8%A9%A9%E6%8A%84%E7%AE%8B.pdf X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=593ac2a32e26dc4180e0449005a1d24a%2F20260523%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260523T090708Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host host:tokyobigaku-academy.7f15927586a77eb1044bcd29267c6502.r2.cloudflarestorage.com host UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>47 45 54 0a 2f 63 6f 6d 6d 75 6e 69 74 79 2f 66 6c 75 65 6e 74 63 6f 6d 2d 6f 69 73 78 53 70 42 37 63 4b 32 30 55 49 31 6e 58 6f 44 79 4f 36 4b 45 34 54 69 35 33 65 67 57 2d 66 6c 75 65 6e 74 63 6f 6d 2d 75 70 70 2d 70 6f 65 74 69 63 61 6c 2d 74 72 61 63 74 61 74 75 73 2d 25 45 38 25 41 39 25 41 39 25 45 36 25 38 41 25 38 34 25 45 37 25 41 45 25 38 42 2e 70 64 66 0a 58 2d 41 6d 7a 2d 41 6c 67 6f 72 69 74 68 6d 3d 41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 26 58 2d 41 6d 7a 2d 43 72 65 64 65 6e 74 69 61 6c 3d 35 39 33 61 63 32 61 33 32 65 32 36 64 63 34 31 38 30 65 30 34 34 39 30 30 35 61 31 64 32 34 61 25 32 46 32 30 32 36 30 35 32 33 25 32 46 75 73 2d 65 61 73 74 2d 31 25 32 46 73 33 25 32 46 61 77 73 34 5f 72 65 71 75 65 73 74 26 58 2d 41 6d 7a 2d 44 61 74 65 3d 32 30 32 36 30 35 32 33 54 30 39 30 37 30 38 5a 26 58 2d 41 6d 7a 2d 45 78 70 69 72 65 73 3d 39 30 30 26 58 2d 41 6d 7a 2d 53 69 67 6e 65 64 48 65 61 64 65 72 73 3d 68 6f 73 74 0a 68 6f 73 74 3a 74 6f 6b 79 6f 62 69 67 61 6b 75 2d 61 63 61 64 65 6d 79 2e 37 66 31 35 39 32 37 35 38 36 61 37 37 65 62 31 30 34 34 62 63 64 32 39 32 36 37 63 36 35 30 32 2e 72 32 2e 63 6c 6f 75 64 66 6c 61 72 65 73 74 6f 72 61 67 65 2e 63 6f 6d 0a 0a 68 6f 73 74 0a 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44</CanonicalRequestBytes>
<SignatureProvided>086a5628f19a60ed1521f4561eeb745424b65cb2958e3a3e7ca084e54d2f639f</SignatureProvided>
</Error>
Thanks!
I entered the ‘Reproduced pattern’ section as a table in the editor, but it did not appear as a table in this post. I have therefore attached a screenshot of the editor.