🚫

【Next.js】Cloudflare R2への画像アップロード時に発生したNotImplementedエラーの解決方法

2025/01/21に公開

Next.jsからCloudflare R2へ画像をアップロードする時にエラーが起きました。

今回のエラー

# エラー文
NotImplemented: Header 'x-amz-checksum-crc32' with value 'xxxxx' not implemented

原因

@aws-sdk/client-s3のバージョンが原因でした。

SDKバージョン「3.729.0」以降、x-amz-checksum-crc32などのチェックサムヘッダーがデフォルトで送信されるようになりました。

Cloudflare R2ではこのヘッダーがサポートされていないため、501 NotImplemented エラーが発生します。

対処法

方法1)SDKをダウングレードする

$ npm install @aws-sdk/client-s3@3.712.0

方法2)ヘッダーを手動で削除する

const s3 = new S3Client({
    region: "auto",
    endpoint: process.env.R2_ENDPOINT!,
    credentials: {
        accessKeyId: process.env.R2_ACCESS_KEY!,
        secretAccessKey: process.env.R2_SECRET_KEY!,
    },
    forcePathStyle: true,
    requestChecksumCalculation: "WHEN_REQUIRED",
});

s3.middlewareStack.add(
  (next) =>
    async (args): Promise<any> => {
      const request = args.request as RequestInit;

      // Remove checksum headers
      const headers = request.headers as Record<string, string>;
      delete headers["x-amz-checksum-crc32"];
      delete headers["x-amz-checksum-crc32c"];
      delete headers["x-amz-checksum-sha1"];
      delete headers["x-amz-checksum-sha256"];
      request.headers = headers;

      Object.entries(request.headers).forEach(
        // @ts-ignore
        ([key, value]: [string, string]): void => {
          if (!request.headers) {
            request.headers = {};
          }
          (request.headers as Record<string, string>)[key] = value;
        }
      );

      return next(args);
    },
  { step: "build", name: "customHeaders" }
);

参考

https://github.com/aws/aws-sdk-js-v3/issues/6810

Discussion