DynamoDB TTL attribute must be a Number
TL;DR — DynamoDB の Time to Live は、指定された TTL 属性が 秒単位の Unix エポックタイムスタンプ を表す Number を保持するときのみアイテムを削除します。"1735689600" のような文字列、ミリ秒値、ISO-8601 の日付、または欠落した属性は黙って無視され、アイテムは決して期限切れになりません。TTL をエポック秒の Number として格納し、影響を受けたアイテムを書き直してください。
意味
# A second UpdateTimeToLive call within one hour of the first raises:
ValidationException (TTL settings can only be modified once per table per hour)
# The quieter failure — no error at all, item just never expires:
TTL attribute "expiresAt" = "2026-01-01T00:00:00Z" ← String, ignored
TTL attribute "expiresAt" = 1735689600000 ← milliseconds: tens of thousands of years awayTTL の有効化(UpdateTimeToLive)は、属性がまだ存在しない、または誤った型でも成功します。DynamoDB は前もって型チェックしません。失敗は後で現れます: バックグラウンドの TTL プロセスは、属性が過去(かつ 5 年以内の過去)の 秒単位の Unix エポックタイムスタンプ を保持する Number のときのみアイテムを削除します。それ以外はすべて「期限切れなし」として扱われます。
発生する理由
- 文字列として格納された — 値が
{"N": "1735689600"}ではなく{"S": "1735689600"}。TTL はN以外の型を無視します。 - 秒ではなくミリ秒 —
Date.now()(JavaScript)はミリ秒を返します。13 桁の値は数万年先の未来なので、アイテムは事実上決して期限切れになりません。 - エポック秒ではなく ISO-8601 / 人間可読の日付文字列。
- 5 年より前の過去のタイムスタンプ — TTL プロセスはアイテムを削除する代わりにそれを無視します。
- TTL に登録されたのとは 別の属性名(名前は大文字小文字を区別します)。
UpdateTimeToLiveを早すぎるタイミングで再度呼び出す — 変更が完全に処理されるまで最大 1 時間かかり、その 1 時間の間に同じテーブルへの追加のUpdateTimeToLive呼び出しはValidationExceptionを発生させます。
修正方法
- TTL 値をエポック秒の Number として書き込みます — JavaScript では
Math.floor(Date.now() / 1000) + ttlSeconds、Python ではint(time.time()) + ttl。決してミリ秒を格納しないでください。 SではなくN型を使います。低レベルクライアントではそれは{"N": "1735689600"}です。Document Client はネイティブの数値を代わりにマーシャルします。- 大文字小文字を含め、登録された属性名に正確に一致させます。
DescribeTimeToLiveで確認します。 - 既存のアイテムをバックフィルします — 修正前に書かれたアイテムは依然として不正な値を持ちます。正しいエポック秒の Number で書き直します。
- TTL 設定変更の間は 1 時間待ちます —
UpdateTimeToLiveは処理に最大 1 時間かかり、そのウィンドウ内のさらなる呼び出しはValidationExceptionで拒否されます。
テーブルを閲覧しながらすべての属性のワイヤー型を見たいですか?DynoTable デスクトップアプリ は N/S/M 型タグをインラインでレンダリングするため、文字列として格納された TTL が、期限切れにならないアイテムのコストになる前に飛び出します。
よくある質問
DynamoDB の TTL がアイテムを削除しないのはなぜですか? TTL 属性は、秒単位の Unix エポックタイムスタンプを保持する Number である必要があります。文字列値、ミリ秒値、ISO 日付、または登録された TTL 属性と一致しない名前は、すべて黙って無視されるため、アイテムは決して期限切れになりません。削除も即時ではありません。DynamoDB は通常、期限切れ時刻から数日以内に期限切れアイテムを削除します。
TTL を有効にするとき DynamoDB は TTL 属性の型を検証しますか?
いいえ。UpdateTimeToLive は、属性が欠落していても誤った型でも成功します。型要件(Number、エポック秒)はバックグラウンドの削除プロセスによってのみ強制されるため、不正な TTL は静かに失敗します。
関連するエラー
- Float / decimal number types not supported — 関連する数値型付けの落とし穴。
- ValidationException (overview)
- 学習: DynamoDB の TTL · DynamoDB のデータ型
参考資料
- Using time to live (TTL) in DynamoDB — Amazon DynamoDB Developer Guide
- Computing time to live (TTL) in DynamoDB — Amazon DynamoDB Developer Guide
- Enable time to live (TTL) in DynamoDB — Amazon DynamoDB Developer Guide
- UpdateTimeToLive — Amazon DynamoDB API Reference
最終検証日 2026-07-13、上記にリンクした公式 AWS ドキュメントに照らして確認しました。