DynamoDB GSI does not project the requested attribute

TL;DR — You queried a Global Secondary Index and asked (via ProjectionExpression or Select=ALL_ATTRIBUTES) for an attribute the index doesn't project. A GSI only returns its own key attributes, the base table's key attributes, and whatever you listed in its projection — nothing else. Either narrow the request to projected attributes, add the attribute to the GSI's projection, or query the base table by primary key.

What it means

ValidationException: One or more parameter values were invalid: Global secondary
index <index_name> does not project <attribute_name>

# or, with Select=ALL_ATTRIBUTES on a KEYS_ONLY / INCLUDE index:
ValidationException: ... does not have the attribute ...

Unlike a Local Secondary Index (which can fetch un-projected attributes from the base item at extra cost), a GSI is a self-contained copy. It physically stores only the attributes in its projection. Asking a GSI query for anything outside that set is unsatisfiable, so DynamoDB rejects the request instead of silently returning partial data.

Why it happens

  • ProjectionType: KEYS_ONLY index queried for a non-key attribute.
  • ProjectionType: INCLUDE index queried for an attribute not in the NonKeyAttributes list.
  • Select: ALL_ATTRIBUTES on a GSI that isn't ProjectionType: ALL.
  • Assuming LSI behavior — expecting a GSI to fetch un-projected attributes from the base table (only LSIs do that).
  • A projection that drifted from the query's needs as the access pattern evolved.

How to fix it

  1. Request only projected attributes — restrict ProjectionExpression to the GSI's keys + its projected set, or drop Select: ALL_ATTRIBUTES.
  2. Add the attribute to the GSI projection — for a new attribute, create/replace the GSI with ProjectionType: INCLUDE (listing it) or ALL. Existing GSIs' projections can't be edited in place; you add a new GSI or recreate it.
  3. Fetch from the base table — use the keys the GSI does return to do a GetItem/BatchGetItem on the base table for the full item.
  4. Use ProjectionType: ALL if you routinely need every attribute from the index (accepting the extra storage/write cost).

Want to see which attributes a GSI actually carries before you query it? The DynoTable desktop app shows each index's projection so you request only what's there — no does not project surprise.

Lavora con DynamoDB senza la Console

DynoTable è un client desktop veloce per DynamoDB — sfoglia le tabelle, esegui query in stile SQL e modifica gli Item localmente.