{"record":{"id":"4ff1216d05ffa551","repo":"apache/shardingsphere","slug":"failed-to-decrypt-the-ciphertext-s-in-s","errorCode":null,"errorMessage":"Failed to decrypt the ciphertext '%s' in '%s'.","messagePattern":"Failed to decrypt the ciphertext '(.+?)' in '(.+?)'\\.","errorType":"exception","errorClass":"DecryptFailedException","httpStatus":null,"severity":"error","filePath":"features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java","lineNumber":77,"sourceCode":"        String originalTableName = columnSegmentBoundInfo.get().getOriginalTable().getValue();\n        String originalColumnName = columnSegmentBoundInfo.get().getOriginalColumn().getValue();\n        ShardingSphereDatabase database = metaData.containsDatabase(columnSegmentBoundInfo.get().getOriginalDatabase())\n                ? metaData.getDatabase(columnSegmentBoundInfo.get().getOriginalDatabase())\n                : this.database;\n        Optional<EncryptRule> rule = database.getRuleMetaData().findSingleRule(EncryptRule.class);\n        if (!rule.isPresent() || !rule.get().findEncryptTable(originalTableName).map(optional -> optional.isEncryptColumn(originalColumnName)).orElse(false)) {\n            return getMergedResult().getValue(columnIndex, type);\n        }\n        Object cipherValue = getMergedResult().getValue(columnIndex, Object.class);\n        EncryptColumn encryptColumn = rule.get().getEncryptTable(originalTableName).getEncryptColumn(originalColumnName);\n        String schemaName = selectStatementContext.getTablesContext().getSchemaName()\n                .orElseGet(() -> new DatabaseTypeRegistry(selectStatementContext.getSqlStatement().getDatabaseType()).getDefaultSchemaName(database.getName()));\n        try {\n            return encryptColumn.getCipher().decrypt(database.getName(), schemaName, originalTableName, originalColumnName, cipherValue);\n            // CHECKSTYLE:OFF\n        } catch (final Exception ex) {\n            // CHECKSTYLE:ON\n            throw new DecryptFailedException(String.valueOf(cipherValue), new SQLExceptionIdentifier(database.getName(), originalTableName, originalColumnName), ex);\n        }\n    }\n}\n","sourceCodeStart":59,"sourceCodeEnd":81,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java#L59-L81","documentation":"EncryptMergedResult.getValue decrypts cipher values for encrypted columns on result merge. When EncryptColumn.getCipher().decrypt(...) throws any Exception, it is rethrown as DecryptFailedException with the ciphertext value, a database/table/column identifier, and the original cause. The rendered message is 'Failed to decrypt the ciphertext '%s' in '%s'.', where the second placeholder is the identifier string.","triggerScenarios":"SELECTing an encrypted column whose stored data cannot be decrypted by the configured algorithm: wrong key in config, data encrypted with a different algorithm (migration/key rotation), corrupted ciphertext, or manually inserted plaintext in a cipher column.","commonSituations":"Key rotation without re-encrypting existing rows; copying a database between environments with different encrypt keys; switching algorithm names (AES to SM4 etc.) while keeping old data; DBAs writing raw values directly into cipher columns.","solutions":["Verify the encrypt key/algorithm in the ShardingSphere config matches what encrypted the stored data","Check the cause chain: a padding/encoding error usually means wrong key; 'bad input length' or garbage output means algorithm mismatch","Re-encrypt existing data with the current key (migration tooling or a one-off decrypt-with-old/encrypt-with-new pass)","Restore corrupted rows from backup or mark them for re-initialization"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"try { byte[] probe = cipher; /* decrypt one known row at startup */ algorithm.decrypt(probe); } catch (Exception e) { throw new IllegalStateException(\"Encrypt key does not match stored data\", e); }","typeGuard":null,"tryCatchPattern":"catch (DecryptFailedException e) { log.cipher(e.getCipherValue()); log.identifier(e.getIdentifier()); /* quarantine row, continue merging others */ }","preventionTips":["Verify the encrypt key against a canary row at startup","Re-encrypt data during key rotation instead of only changing config","Prevent manual writes to cipher columns (permissions, triggers)"],"tags":["encrypt","decrypt","key-mismatch","data-corruption"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}