How to encode CJK filenames in R2?

Hello. I’m trying to upload a file with CJK filename.

  1. Upload a file with aws-sdk

    • file name corrupted: 테스트.png
    • S3 URL cretated: %C3%A1%C2%84%C2%90%C3%A1%C2%85%C2%A6%C3%A1%C2%84%C2%89%C3%A1%C2%85%C2%B3%C3%A1%C2%84%C2%90%C3%A1%C2%85%C2%B3.png
  2. Upload a file with aws-sdk, encode file name with encodeURIComponent()

    • file name not corrupted: 테스트.png
    • S3 URL not created: undefined
  3. Upload a file with R2 dashboard

    • file name not corrupted: 테스트.png
    • S3 URL created: %E1%84%90%E1%85%A6%E1%84%89%E1%85%B3%E1%84%90%E1%85%B3.png

I think this problem is related with text encoding, since R2 dashboard uploads file with no problem, but I don’t know how to encode data correctly.

How can I solve this problem?

<Case 01>

<Case 02>

<Case 03>

Which of the AWS sdk clients are you using and what version?

I have tried with the aws-sdk/client-s3 as indicated in the docs here Configure `aws-sdk-js-v3` for R2 · Cloudflare R2 docs and I cannot seem to reproduce your issue even with the file name you posted.

You don’t need to encode the object key before running the PutObject command, it should just work.

The URL on the dash in the Object view is encoded on purpose, so that one can just copy and paste it anywhere without having to worry about encoding the params.

Here is a snippet of the code I ran in javascript as a reference, please let me know how it goes.

import {
  } from "@aws-sdk/client-s3";
  import * as path from "path";
  import * as fs from 'fs';
  const S3 = new S3Client({
    region: "auto",
    endpoint: `https://<ACCOUNT_ID>`,
    credentials: {
      accessKeyId: "<ACCESS_KEY_ID>",
      secretAccessKey: "<ACCESS_KEY_SECRET>",
  const file = "테스트.png"; // Path to and name of object. For example '../myFiles/index.js', for me the image is in the same folder as this javascript file.
  const fileStream = fs.createReadStream(file);
  const fileName = path.basename(file)
  // Set the parameters
  const uploadParams = {
    Bucket: "<BUCKET_NAME>",
    Key: fileName,
    Body: fileStream,
    ContentType: 'image/png' // you can omit this
  // Upload file to specified bucket.
  const run = async () => {
      try {
      const data = await S3.send(new PutObjectCommand(uploadParams));
      console.log("Success", data);
      return data; 
    } catch (err) {
      console.log("Error", err);

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.