ValidationException: Query condition missed key schema element
TL;DR — KeyConditionExpression には、パーティションキーに対する等価条件(=)が必ず必要です。キー以外の属性で検索したいなら、その属性をキーに持つ GSI/LSI に対する Query が必要です — または FilterExpression 付きの Scan を使います。
意味
完全なメッセージはたいてい次のようになります。
ValidationException: Query condition missed key schema element: pkコロンの後ろの名前は、あなたのテーブルのパーティションキー属性なので、テーブルごとに変わります。
Query は キー に対してしか動きません。DynamoDB は、KeyConditionExpression がパーティションキーをまったく含んでいないか、テーブル(または対象のインデックス)のパーティション/ソートキーではない属性を指定している、と告げています。
発生する理由
KeyConditionExpressionが、パーティションキーではなく 通常の属性(例:email、status)で絞り込んでいる。- ベーステーブル に対してクエリしているのに、その属性は GSI 上でしかキーになっていない —
IndexNameを忘れている。 - パーティションキーはあるが
=以外の演算子を使っている(パーティションキーは完全一致でなければならず、<、>、begins_with、betweenをサポートするのは ソート キーだけです)。 - 属性名のタイプミスで、スキーマと一致しなくなっている。
修正方法
- パーティションキーに
=を使ってクエリします。 すべての Query にはpk = :pk(テーブルの実際のキー名を使う)が必要です。 - キー以外の属性でクエリしたいですか? その属性をパーティションキーに持つ GSI を作成し、
IndexNameを渡します。 - たまにしかアクセスしませんか?
Queryの代わりにFilterExpression付きのScanを使います — ただし Scan はテーブル全体を読むことに注意してください。
例
import {DynamoDBClient} from '@aws-sdk/client-dynamodb';
import {DynamoDBDocumentClient, QueryCommand} from '@aws-sdk/lib-dynamodb';
const doc = DynamoDBDocumentClient.from(new DynamoDBClient({}));
// Query the base table by its partition key:
await doc.send(
new QueryCommand({
TableName: 'Orders',
KeyConditionExpression: 'pk = :pk',
ExpressionAttributeValues: {':pk': 'USER#123'}
})
);
// Query by a non-key attribute → use a GSI that keys on it
// ("status" is a DynamoDB reserved word, so alias it with #status):
await doc.send(
new QueryCommand({
TableName: 'Orders',
IndexName: 'byStatus',
KeyConditionExpression: '#status = :s',
ExpressionAttributeNames: {'#status': 'status'},
ExpressionAttributeValues: {':s': 'SHIPPED'}
})
);よくある質問
「Query condition missed key schema element」はどういう意味ですか? KeyConditionExpression がパーティションキーをまったく含んでいないか、対象のテーブルまたはインデックスのパーティションキー/ソートキーではない属性を指定しています。すべての Query には、パーティションキーに対する等価条件が必要です。
キー以外の属性で DynamoDB をクエリするには?
その属性をパーティションキーに持つ GSI を作成し、Query で IndexName を渡します — あるいは、たまにしかアクセスしないなら FilterExpression 付きの Scan を使います。ただし Scan はテーブル全体を読むことを念頭に置いてください。
再現方法
条件にソートキーしか指定していない Query です。
await client.send(
new QueryCommand({
TableName: 'orders',
KeyConditionExpression: 'sk = :s',
ExpressionAttributeValues: {':s': {S: 'META'}}
})
);実際の出力:
ValidationException: Query condition missed key schema element
HTTP 400すべての Query は、ちょうど1つのパーティションキーを固定しなければなりません。ソートキーだけで検索したいという要望は、そのアクセスパターンに Query ではなく GSI が必要だという典型的なサインです — あるいは、本当にすべてのパーティションを読む必要があるなら Scan です。
関連するエラー
- The provided key element does not match the schema
- ValidationException (overview)
- Code example: Query in Node.js · in Python (boto3) — 正しく書かれた KeyConditionExpression。
- 学習: Query と Scan · キー条件式
参考資料
- Query — Amazon DynamoDB API Reference
- Reserved words in DynamoDB — Amazon DynamoDB Developer Guide
- Using Global Secondary Indexes in DynamoDB — Amazon DynamoDB Developer Guide
最終検証日 2026-07-13、上記にリンクした公式 AWS ドキュメントに照らして確認しました。
2026-07-26 に DynamoDB Local 2.x と AWS SDK for JavaScript v3.1095.0 で再現しました — 上記の出力はそのままの逐語です。