4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【小ネタ】AWS SDKでS3コマンド実行時に "The XML you provided was not well-formed or did not validate against our published schema" と言われたら……

Last updated at Posted at 2025-09-19

"The XML you provided was not well-formed or did not validate against our published schema" と言われたら……

Node.js の AWS SDK で、S3のコマンド実行時に

MalformedXML: The XML you provided was not well-formed or did not validate against our published schema

と言われたら、 S3コマンドオブジェクトに余計なプロパティを渡してしまっていないかチェックしましょう!

典型的な例として、ListObjectsV2Command の返り値である _Object[] (S3 Getで得られる色々な情報が入ったオブジェクト)をキャストしてそのまま渡しているケースが考えられます。

問題のあるコードの例
import {
  type _Object,
  type ObjectIdentifier,
  type S3Client,
  DeleteObjectsCommand,
  ListObjectsV2Command,
} from "@aws-sdk/client-s3"; // バージョン '3.887.0' で検証 

const deleteAllObjects = async (s3Client: S3Client, bucketName: string, prefix: string) => {

  // 削除対象のファイルの取得
  // 一気に取得できない場合の継続トークンの処理などは省略
  const listCommand = new ListObjectsV2Command({
    Bucket: bucketName,
    Prefix: prefix,
  });
  const listResponse = await s3Client.send(listCommand);
  const filesToDelete: _Object[] = listResponse.Contents ?? [];

  // 削除対象のファイルの削除
  const deleteCommand = new DeleteObjectsCommand({
    Bucket: bucketName,
    Delete: {
      // 🙅 NG: { Key: string } を含む _Object[] 型をそのまま渡しているが、これをやるとリクエストエラーになる
      Objects: filesToDelete.Contents as { Key: string }[],

      // 👍️ OK: 正しくは以下のように Key プロパティを抽出して渡す (ObjectIdentifier[] 型に合わせる)
      Objects: filesToDelete.map(obj => ({ Key: obj.Key! })),
    },
  })
  await s3Client.send(deleteCommand);
}

上記は互換サーバ (MinIO) ではエラーになりませんでした。いきなり結合や本番で遭遇するかもしれませんので、気をつけましょう。

具体的に何が問題なのか深堀りしてみる

ListObjectsV2Command の返り値 _Object[] には以下のようなプロパティが含まれています。 Key の他に色々含まれていることが分かります。

interface _Object {
  Key?: string;
  LastModified?: Date;
  ETag?: string;
  Size?: number;
  StorageClass?: string;
  Owner?: {
    DisplayName?: string;
    ID?: string;
  };
}

一方、DeleteObjectsCommandObjects に期待される型は以下だけです。通常は Key プロパティのみを指定するでしょう。

interface ObjectIdentifier {
  Key: string;
  VersionId?: string;
}

では、 ListObjectsV2Command で取得された _Object を渡すと実際にどのようなリクエスト電文を送っているか、デバッグ実行で実際に確認してみましょう。@smithy/middleware-serde@4.0.8src/serializerMiddleware.ts のコメントあたりをチェックすれば確認できます。

送信電文(_Objectそのままを渡した場合)
<?xml version="1.0" encoding="UTF-8"?>
<Delete xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Object>
        <Key>test/foo/bar/filesToBeDeleted.msu8</Key>
        <ETag>&quot;9473fdd0d880a43c21b7778d34872157&quot;</ETag>
        <Size>12</Size>
    </Object>
    <Quiet>false</Quiet>
</Delete>

<!--
  🙅 エラー: The XML you provided was not well-formed or did not validate against our published schema
-->

この記事に書いてあるとおりにエラーとなりました。ちなみに余計なプロパティをコマンドに付けて送ろうとしてもXMLへのシリアライゼーション過程で省かれるようです。シリアライザがキーを固定して値を拾っているようです。

次に正常なリクエストを送るために、Key プロパティだけを抽出して渡した場合のリクエスト電文を確認してみます。

送信電文(Keyプロパティだけ抽出して渡した場合)
<?xml version="1.0" encoding="UTF-8"?>
<Delete xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Object>
        <Key>test/foo/bar/filesToBeDeleted.msu8</Key>
    </Object>
    <Quiet>false</Quiet>
</Delete>

<!--
   👍️ OK: 正常に削除される
-->

これは成功しました。それなら、ETagSize のどちらかがエラーの原因なのか?

送信電文(ETagプロパティも抽出して渡した場合)
<?xml version="1.0" encoding="UTF-8"?>
<Delete xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Object>
        <Key>test/foo/bar/filesToBeDeleted.msu8</Key>
        <ETag>&quot;9473fdd0d880a43c21b7778d34872157&quot;</ETag>
    </Object>
    <Quiet>false</Quiet>
</Delete>

<!--
   👍️ OK: 正常に削除される
-->

ETag は問題ないようです。

では次に Size を渡してみます。

送信電文(Sizeプロパティも抽出して渡した場合)
<?xml version="1.0" encoding="UTF-8"?>
<Delete xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Object>
        <Key>test/foo/bar/filesToBeDeleted.msu8</Key>
        <Size>12</Size>
    </Object>
    <Quiet>false</Quiet>
</Delete>

<!--
  🙅 エラー: The XML you provided was not well-formed or did not validate against our published schem
-->

そういうことで Sizeプロパティを渡すとリクエストが失敗する ようでした。ええ〜!?1

  • 実験リージョン: ap-northeast-1
  • AWS SDK: @aws-sdk/client-s3@3.887.0
  1. もちろんAWS SDKのXMLシリアライザの出力と、AWSサービス側のXMLスキーマが異なっているように見えることについて心外であるという意味合いです

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?