Consistent reads are not supported on global secondary indexes

En bref — Tu as défini ConsistentRead: true sur un Query ou un Scan qui cible un index secondaire global. Les GSI se répliquent depuis la table de base de façon asynchrone et ne servent que des lectures en cohérence à terme — le drapeau est une erreur stricte, pas une préférence. Retire le drapeau, ou si tu as réellement besoin d'une cohérence lecture-après-écriture, lis la table de base (ou intègre la clé dans un LSI).

Ce que ça signifie

ValidationException: Consistent reads are not supported on global secondary indexes

Un GSI est physiquement sa propre structure d'index avec ses propres partitions et sa propre capacité ; DynamoDB y propage les écritures de la table de base de façon asynchrone. Comme un élément que tu viens d'écrire peut ne pas encore être arrivé dans l'index, DynamoDB ne peut pas honorer une lecture fortement cohérente sur celui-ci — donc ConsistentRead: true combiné à un IndexName de GSI est rejeté d'emblée. La documentation AWS est explicite : interroge un GSI avec ConsistentRead à true et tu reçois une ValidationException.

Les index secondaires locaux sont différents : un LSI partage sa partition avec la table de base, donc ConsistentRead: true y est pris en charge.

Pourquoi ça arrive

  • Le drapeau a été défini globalement — un utilitaire de requête partagé ou un wrapper de client met par défaut ConsistentRead: true pour chaque lecture, et un chemin d'appel ajoute un IndexName pointant vers un GSI.
  • Un LSI est devenu un GSI — du code écrit pour un index local (où le drapeau est légal) a été pointé vers un index global.
  • Requête de table de base copiée-collée — une requête qui utilisait légitimement la forte cohérence sur la table a été réutilisée avec un IndexName ajouté.

Comment corriger

  1. Retire ConsistentRead des lectures de GSI (ou mets-le à false — la valeur par défaut) :

    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. Besoin de lecture-après-écriture ? Interroge la table de base avec ConsistentRead: true — possible dès lors que la clé que tu recherches est la clé de partition de la table elle-même.

  3. Même clé de partition, tri différent ? Modélise-le comme un LSI (créé à la création de la table), qui prend en charge les lectures cohérentes.

  4. Ou absorbe le décalage dans l'application — la propagation des GSI est généralement rapide ; pour les flux d'UI, renvoyer les données tout juste écrites que tu as déjà vaut mieux que relire l'index.

L'application de bureau DynoTable montre les index de chaque table et te laisse les interroger directement — et comme elle sait quel index est global et lequel est local, cette classe d'erreur ne se présente tout simplement pas.

Erreurs liées

Références

Dernière vérification le 2026-07-13 par rapport à la documentation officielle AWS liée ci-dessus.

Travaille avec DynamoDB sans la Console

DynoTable est un client de bureau rapide pour DynamoDB — parcours les tables, exécute des requêtes de style SQL et édite les items en local.