Consistent reads are not supported on global secondary indexes

TL;DR — You set ConsistentRead: true on a Query or Scan that targets a global secondary index. GSIs replicate from the base table asynchronously and only serve eventually consistent reads — the flag is a hard error, not a preference. Drop the flag, or if you truly need read-after-write consistency, read the base table (or design the key into an LSI).

What it means

ValidationException: Consistent reads are not supported on global secondary indexes

A GSI is physically its own index structure with its own partitions and capacity; DynamoDB propagates base-table writes into it asynchronously. Because an item you just wrote may not have arrived in the index yet, DynamoDB cannot honor a strongly consistent read against it — so ConsistentRead: true combined with a GSI IndexName is rejected outright. The AWS documentation is explicit: query a GSI with ConsistentRead set to true and you receive a ValidationException.

Local secondary indexes are different: an LSI shares its partition with the base table, so ConsistentRead: true is supported there.

Why it happens

  • The flag was set globally — a shared query helper or client wrapper defaults ConsistentRead: true for every read, and one call path adds an IndexName pointing at a GSI.
  • An LSI became a GSI — code written for a local index (where the flag is legal) was pointed at a global one.
  • Copy-pasted base-table query — a query that legitimately used strong consistency on the table was reused with IndexName added.

How to fix it

  1. Remove ConsistentRead from GSI reads (or set it to false — the default):

    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'}}
      })
    );
  2. Need read-after-write? Query the base table with ConsistentRead: true — possible whenever the key you're looking up is the table's own partition key.

  3. Same partition key, different sort? Model it as an LSI (created at table creation), which supports consistent reads.

  4. Or absorb the lag in the application — GSI propagation is typically fast; for UI flows, returning the just-written data you already have beats re-reading the index.

  5. Audit shared query helpers. A default ConsistentRead: true on every read breaks the moment any call path adds a GSI IndexName.

Check it in DynoTable

DynoTable knows which indexes are GSIs vs LSIs — GSI queries never send ConsistentRead: true. Open a table with ⌘K, pick an index from the dropdown, and run the query without the flag.

When you need read-after-write, query the base table instead — the Query Builder generates the correct parameters per target. Switch profiles with ⌘P; see Connect to AWS and Install.

Sources

References

Last verified 2026-07-13 against the official AWS documentation linked above.

Work with DynamoDB without the Console

A fast DynamoDB desktop client that runs the real SQL DynamoDB can’t — JOINs, GROUP BY, aggregates — with visual editing and an AI agent on your own Bedrock keys.

Free 30-day trial, no credit card — then the Free plan with no time limit.