
AWS SDK for JavaScript v3 で requestTimeout を設定したのに、時間切れにならない原因を教えてください
困っていること
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)の分だけ長くなります。
次の順で直してください。
-
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 のバージョンではなく、このパッケージのバージョンで判断してください。 -
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 になりました。

UPGRADING.md の requestTimeout の説明は次のとおりです(既定の 0 は時間切れなし)。
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)のソースコードのコメントに書かれていました。
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 の結果です。

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







