Consistent reads are not supported on global secondary indexes
TL;DR — 你在一個以全域secondary index 為目標的 Query 或 Scan 上設定了 ConsistentRead: true。GSI 以非同步方式從基礎表格複製,且只提供最終一致讀取 — 這個旗標是硬性錯誤,而非偏好設定。移除該旗標;如果你真的需要寫後即讀的一致性,改讀基礎表格(或將該鍵設計進 LSI)。
這是什麼意思
ValidationException: Consistent reads are not supported on global secondary indexesGSI 在實體上是它自己的索引結構,有自己的 partition 與容量;DynamoDB 以非同步方式將基礎表格的寫入傳播到其中。由於你剛寫入的項目可能尚未抵達索引,DynamoDB 無法對它兌現強一致讀取 — 因此 ConsistentRead: true 與 GSI IndexName 結合會被直接拒絕。AWS 文件明確指出:以 ConsistentRead 設為 true 查詢 GSI,你會收到 ValidationException。
Local secondary index 則不同:LSI 與基礎表格共用其 partition,因此那裡支援 ConsistentRead: true。
為什麼會發生
- 旗標被全域設定 — 共用的查詢輔助程式或用戶端包裝器對每次讀取預設
ConsistentRead: true,而某條呼叫路徑加了指向 GSI 的IndexName。 - LSI 變成了 GSI — 為 local 索引撰寫的程式碼(旗標在那裡合法)被指向了 global 索引。
- 複製貼上的基礎表格查詢 — 一個在表格上合法使用強一致的查詢被重用並加上了
IndexName。
如何修正
從 GSI 讀取中移除
ConsistentRead(或設為false— 預設值):await client.send( new QueryCommand({ TableName: 'Orders', IndexName: 'status-index', KeyConditionExpression: '#s = :open', // ConsistentRead: true ← delete this line for a GSI ExpressionAttributeNames: {'#s': 'status'}, ExpressionAttributeValues: {':open': {S: 'OPEN'}} }) );需要寫後即讀? 以
ConsistentRead: true查詢基礎表格 — 只要你要查找的鍵是表格自己的 partition key,就可行。相同 partition key、不同 sort? 將它建模為 LSI(在建立表格時建立),它支援一致讀取。
或在應用中吸收延遲 — GSI 傳播通常很快;對 UI 流程而言,回傳你手上已有的剛寫入資料,勝過重新讀取索引。
DynoTable 桌面應用程式顯示每個表格的索引並讓你直接查詢它們 — 而且因為它知道哪個索引是全域、哪個是本地,這類錯誤根本不會出現。
相關錯誤
- GSI throttles the base table — GSI 的寫入端耦合。
- The table does not have the specified index
- Cannot update GSI while it is being created
- 程式碼範例:Query a GSI in Node.js — 正確完成的最終一致 GSI 查詢。
- 學習:Why GSIs are eventually consistent · GSI vs LSI · Consistency
References
- Query — Amazon DynamoDB API Reference
- Using Global Secondary Indexes in DynamoDB — Amazon DynamoDB Developer Guide
- Constraints in Amazon DynamoDB — Amazon DynamoDB Developer Guide
最後驗證於 2026-07-13,對照上方連結的 AWS 官方文件。