AWS SDK for JavaScript v3 で requestTimeout を設定したのに、時間切れにならない原因を教えてください

AWS SDK for JavaScript v3 で requestTimeout を設定したのに、時間切れにならない原因を教えてください

AWS SDK for JavaScript v3 で `requestTimeout` を設定しても効かなくなった問題と、その解決方法を紹介します。@smithy/node-http-handler の仕様変更により `throwOnRequestTimeout: true` の設定が必要になりました。
2026.10.25

困っていること

AWS SDK for JavaScript v3 で、クライアントの requestHandler に requestTimeout: 5_000 を設定しています。
SDK を更新してから、応答が遅くても 5 秒でエラーにならず、応答が返るまで待つようになりました。
ログには次の警告が出ていました。

@smithy/node-http-handler - [WARN] a request has exceeded the configured 5000 ms requestTimeout. Init client requestHandler with throwOnRequestTimeout=true to turn this into an error.

requestTimeout が効かない原因と、5 秒でエラーにする方法を教えてください。

どう対応すればいいの?

@smithy/node-http-handler 4.4.0 以降では、requestTimeout を超えても、既定では警告だけでエラーになりません。
1 回の試行を 5 秒でエラーにするには、requestHandler に throwOnRequestTimeout: true を足してください。再試行があるため、send() 全体の時間は、試行の回数(maxAttempts)の分だけ長くなります。

次の順で直してください。

  1. npm ls @smithy/node-http-handler で、4.4.0 以降が入っているかを確認します。SDK の UPGRADING.md では、throwOnRequestTimeout は SDK 3.910.0 からの設定とされています。ただし、3.901.0 の @aws-sdk/client-s3 を入れ直したときも、依存の解決で 4.12.1 が入りました。SDK のバージョンではなく、このパッケージのバージョンで判断してください。

  2. requestHandler に throwOnRequestTimeout: true を足します。直し方の例は次のとおりです。

    const client = new S3Client({
      region: "ap-northeast-1",
      requestHandler: {
        requestTimeout: 5_000,
        throwOnRequestTimeout: true,
      },
    });
    

maxAttempts: 1 にして試し、応答が遅いときに 5 秒で TimeoutError になれば設定できています。

確認してみた

Node.js v26.7.0 で、15 秒後に応答を返すローカルの HTTP サーバーに S3Client を向けて、時間を測りました(コマンドの slow は、この遅い応答を返す指定です)。
client.mjs のうち、クライアントを作る部分は次のとおりです。perCommand は、send() の第 2 引数で requestTimeout を渡すときの切り替えです。socketTimeout は別の比較に使った指定で、この記事の結果では付けていません。時間を測りやすくするため、再試行を止めています(--attempts を付けないときは maxAttempts: 1)。

const requestHandler = { requestTimeout: perCommand ? undefined : 5_000 };
if (throwOnRequestTimeout) requestHandler.throwOnRequestTimeout = true;
if (socketTimeout) requestHandler.socketTimeout = socketTimeout;

const client = new S3Client({
  region: "ap-northeast-1",
  endpoint: `http://127.0.0.1:${server.address().port}`,
  forcePathStyle: true,
  credentials: { accessKeyId: "AKIDEXAMPLE", secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" },
  maxAttempts: opt("--attempts") ?? 1,
  requestHandler,
});

@smithy/node-http-handler は 4.12.1 です。--throw(throwOnRequestTimeout: true)を付けて実行すると、maxAttempts: 1 の設定では、5.0 秒で TimeoutError になりました。

01

UPGRADING.md の requestTimeout の説明は次のとおりです(既定の 0 は時間切れなし)。

https://github.com/aws/aws-sdk-js-v3/blob/v3.1154.0/UPGRADING.md#L80-L90

If exceeded, a warning will be emitted unless throwOnRequestTimeout=true, in which case a TimeoutError will be thrown.

警告だけになるのは、Node.js の HTTP 通信を受け持つ @smithy/node-http-handler の 4.4.0 で入った動きです。それまでの requestTimeout は、ソケットが何も通信しない時間の上限として働いていました。なお、この理由は @smithy/types(smithy-typescript)のソースコードのコメントに書かれていました。

https://github.com/smithy-lang/smithy-typescript/blob/761d89ca4fa20355d8a34633a11e1dbd2819360e/packages/types/src/http/httpHandlerInitialization.ts#L43-L44

Because requestTimeout was for a long time incorrectly being set as a socket idle timeout, users must also opt-in for request timeout thrown errors.

同じ client.mjs(maxAttempts: 1)で、バージョンごとに比べました。4.3.0 では 5 秒で TimeoutError になりました。4.4.0 と 2026 年 10 月時点の最新の 4.12.1 では、5 秒の時点で警告を出し、15 秒後に成功しました。次の画像は 4.12.1 の結果です。

02

注意点

  • TimeoutError の後も、SDK は再試行します。--throw --attempts 3(throwOnRequestTimeout: true、maxAttempts: 3)で実行しました。send() 全体は約 15 秒かかり、3 回試行した後に TimeoutError になりました。冪等でない操作(2 回実行されると困る操作)は、二重に実行されることがあります。
  • send() の第 2 引数で渡した requestTimeout も、throwOnRequestTimeout がないと警告だけでした。throwOnRequestTimeout は requestHandler に書きます。

参考資料


AWSテクニカルサポートノートについて

過去にクラスメソッドのAWS総合支援サービスで頂いたお問合せの中から、通常のAWS利用時でも有益になりうる情報をテクニカルサポートチームがTIPSとしてご紹介しています。技術サポートは、無料でご提供しております。詳細は下記ボタンからご覧ください。

クラスメソッドのAWSサポートの詳細を見る

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事