DynamoDB TTL attribute must be a Number

TL;DR — DynamoDB 的 Time to Live 只有在其指定的 TTL 属性持有一个表示以秒为单位的 Unix 纪元时间戳的 Number 时才删除项目。一个像 "1735689600" 的 String、一个毫秒值、一个 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 away

启用 TTL(UpdateTimeToLive)即使在属性尚不存在或类型错误时也会成功——DynamoDB 不会预先做类型检查。失败稍后才显现:后台 TTL 进程只有当属性是一个持有过去(且不早于五年前)的以秒为单位的 Unix 纪元时间戳Number 时才删除项目。其他任何东西都被当作"无过期"。

为什么会发生

  • 存储为 String——值是 {"S": "1735689600"} 而不是 {"N": "1735689600"}。TTL 忽略非 N 类型。
  • 毫秒而非秒——Date.now()(JavaScript)返回毫秒;一个 13 位的值在数万年后的未来,因此项目实际上永不过期。
  • 一个 ISO-8601 / 人类可读日期字符串而非纪元秒。
  • 一个早于五年前的时间戳——TTL 进程会忽略它,而不是删除项目。
  • 一个与用 TTL 注册的名称不同的属性名(名称区分大小写)。
  • 过早再次调用 UpdateTimeToLive——该变更需要最多一小时才能完全处理,而在那一小时内对同一张表的任何额外 UpdateTimeToLive 调用都会引发一个 ValidationException

如何修复

  1. 把 TTL 值写为一个纪元秒 Number——JavaScript 中是 Math.floor(Date.now() / 1000) + ttlSeconds,Python 中是 int(time.time()) + ttl。绝不存储毫秒。
  2. 使用 N 类型,而非 S。用底层客户端是 {"N": "1735689600"};文档客户端会为你 marshal 一个原生数字。
  3. 精确匹配注册的属性名,包括大小写。用 DescribeTimeToLive 确认它。
  4. 回填现有项目——修复之前写入的项目仍携带错误的值;用一个正确的纪元秒 Number 重新写入它们。
  5. 在 TTL 配置变更之间等待一小时——UpdateTimeToLive 需要最多一小时来处理,而在那个窗口内进一步的调用会被以一个 ValidationException 拒绝。

想在浏览一张表时看到每个属性的传输类型?DynoTable 桌面应用内联渲染 N/S/M 类型标记,因此一个存为 String 的 TTL 会在它让你损失一个未过期项目之前跳出来。

常见问题

为什么我的 DynamoDB TTL 没有删除项目? TTL 属性必须是一个持有以秒为单位的 Unix 纪元时间戳的 Number。一个 String 值、一个毫秒值、一个 ISO 日期,或一个与注册的 TTL 属性不匹配的名称都会被静默忽略,因此项目永不过期。删除也不是即时的——DynamoDB 通常在项目过期时间的几天内移除它们。

当我启用 TTL 时,DynamoDB 会验证 TTL 属性类型吗? 不会。即使属性缺失或类型错误,UpdateTimeToLive 也会成功。类型要求(Number、纪元秒)只由后台删除进程强制执行,这就是为什么一个错误的 TTL 会静静地失败。

相关错误

参考资料

最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。

无需控制台即可使用 DynamoDB

一款快速的 DynamoDB 桌面客户端,可运行 DynamoDB 无法执行的真正 SQL——JOINs、GROUP BY、聚合——并支持可视化编辑和运行在你自己的 Bedrock 密钥上的 AI agent。

30 天免费试用,无需信用卡 — 之后为无时间限制的免费版。