serverless/serverless · error · ServerlessError
COGNITO_KMS_KEY_ID_NOT_SAME_FOR_SINGLE_USER_POOL
COGNITO_KMS_KEY_ID_NOT_SAME_FOR_SINGLE_USER_POOL
Error message
Only one KMS Key for can be configured per Cognito User Pool. Affected Cognito User Pool: "${currentPoolName}". What it means
A single Cognito user pool can only be associated with one KMS key. If two triggers for the same pool specify different kmsKeyId values, checkKmsArn rejects the mismatch.
Source
Thrown at packages/serverless/lib/plugins/aws/package/compile/events/cognito-user-pool.js:392
return null
}
checkKmsArn(kmsKeyId, poolKmsIdMap, currentPoolName) {
// KMSKeyId is only used (and is required) with Custom Sender Sources
if (!kmsKeyId) {
throw new ServerlessError(
`KMS Key must be set when using a Custom Sender Source Trigger (CustomSMSSender and/or CustomEmailSender). Affected Cognito User Pool: "${currentPoolName}".`,
'COGNITO_KMS_KEY_NOT_SET',
)
}
const previousKmsId = poolKmsIdMap.get(currentPoolName)
if (
previousKmsId !== undefined &&
previousKmsId !== kmsKeyId &&
JSON.stringify(previousKmsId) !== JSON.stringify(kmsKeyId)
) {
throw new ServerlessError(
`Only one KMS Key for can be configured per Cognito User Pool. Affected Cognito User Pool: "${currentPoolName}".`,
'COGNITO_KMS_KEY_ID_NOT_SAME_FOR_SINGLE_USER_POOL',
)
}
poolKmsIdMap.set(currentPoolName, kmsKeyId)
}
findUserPoolsAndFunctions() {
const userPools = []
const cognitoUserPoolTriggerFunctions = []
// Iterate through all functions declared in `serverless.yml`
this.serverless.service.getAllFunctions().forEach((functionName) => {
const functionObj = this.serverless.service.getFunction(functionName)
if (functionObj.events) {
functionObj.events.forEach((event) => {
if (event.cognitoUserPool) {View on GitHub (pinned to b9d7ea51c8)
Solutions
- Use the same kmsKeyId for every trigger on a given pool.
- During key rotation, update all triggers for that pool together.
- Centralize the kmsKeyId in a custom variable so all triggers reference one source.
Example fix
# before
- cognitoUserPool: { pool: MyPool, trigger: CustomSMSSender, kmsKeyId: arn:.../key/aaa }
- cognitoUserPool: { pool: MyPool, trigger: CustomEmailSender, kmsKeyId: arn:.../key/bbb }
# after
- cognitoUserPool: { pool: MyPool, trigger: CustomSMSSender, kmsKeyId: arn:.../key/aaa }
- cognitoUserPool: { pool: MyPool, trigger: CustomEmailSender, kmsKeyId: arn:.../key/aaa } Defensive patterns
Strategy: validation
Validate before calling
function inconsistentKmsPerPool(service) {
const map = {};
for (const e of allCognitoEvents(service)) {
if (!e.kmsKeyId) continue;
if (map[e.pool] && map[e.pool] !== e.kmsKeyId) return e.pool;
map[e.pool] = e.kmsKeyId;
}
return null;
} Prevention
- Use one kmsKeyId variable per pool.
- Update all triggers together during key rotation.
When it happens
Trigger: poolKmsIdMap.get(currentPoolName) returns a previously seen key; if it differs from the new kmsKeyId (by value or JSON) the throw fires.
Common situations: Two custom-sender triggers on one pool pointing at different KMS keys; updating the key on only some triggers during a rotation; copy-paste from another pool's config.
Related errors
- COGNITO_KMS_KEY_NOT_SET
- COGNITO_INVALID_LAMBDA_VERSION
- COGNITO_LAMBDA_VERSION_NOT_SUPPORTED
- COGNITO_MULTIPLE_USER_POOLS_PER_FUNCTION
- LAMBDA_EDGE_UNSUPPORTED_TIMEOUT_VALUE
AI-assisted analysis of serverless/serverless@b9d7ea51c8 (2026-08-13).
Data as JSON: /api/errors/da9d45350b2501c1.
Report an issue: GitHub.