PDB Upgrade Stuck in RESTRICTED Mode: Finding the Missing TDE Key
While I will not cover the full upgrade steps in this post, I would like to share a specific issue we encountered during a non-CDB to PDB migration. This post focuses on what to do when the database remains in RESTRICTED mode after running noncdb_to_pdb.sql due to encryption-related errors.
SQL> select name, open_mode, restricted from v$pdbsNAME OPEN_MODE RESTRICTEDPDB$SEED READ ONLY NO MYTESTPDB READ WRITE YES
In one of the environments we were upgrading, we faced encryption-related violations even though there were no encrypted tablespaces in DBA_TABLESPACES (ENCRYPTED='YES').
The violation reported in PDB_PLUG_IN_VIOLATIONS was similar to the following:
Error Violation:
Wallet Key NeededCause:
PDB needs to import keys from source.Action:
Import keys from source.
At first glance, this was confusing because there did not appear to be any encrypted tablespaces in the source database. That was exactly the situation we encountered.
Our first step was to investigate the wallet side. Fortunately, the required master key identifier was clearly mentioned in the alert.log, which significantly helped narrow down the issue. You will have something like this ( which i changed alot but similar like this)
(3):KZTDE:kztsmptc: Missing Key ID: ARfZOD6QcF+Sv+HlNAy5LQPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
You may use query provided below to detect the encyrption keys you need.
SELECT utl_raw.Cast_to_varchar2( utl_encode.Base64_encode('01' || Substr(mkeyid, 1, 4))) || utl_raw.Cast_to_varchar2(utl_encode.Base64_encode( Substr(mkeyid, 5, Length(mkeyid)))) masterkeyid_base64, x.*FROM x$kcbtek xWHERE blks_enc > 0ORDER BY 1;
At this point, the challenge became importing the required encryption keys into the CDB wallet for a database that seemingly had no encrypted tablespaces at all.
We started searching through the wallet backups we had available. Specifically, we checked all Auto Login wallet (.sso) backups one by one to determine which wallet contained the missing key referenced in the alert log.
I used Jimmy’s blog post ORA-28374: typed master key not found in wallet to gather more information on the issue. You may also want to take a look at it.
We queried the wallets using the command provided below, which fortunately does not require knowing the wallet passwords.
Luckily, I was able to locate the required encryption key in one of the old wallet backups.
[oracle@myserver ~]$ orapki wallet display -wallet /u01/app/oracle/myluckywallet/tde/Oracle PKI Tool Release 19.0.0.0.0 - ProductionVersion 19.4.0.0.0Copyright (c) 2004, 2026, Oracle and/or its affiliates. All rights reserved.Requested Certificates:Subject: CN=oracleUser Certificates:Oracle Secret Store entries:ORACLE.SECURITY.DB.ENCRYPTION.ARfZOD6QcF+Sv+HlNAy5LQPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAORACLE.SECURITY.DB.ENCRYPTION.MASTERKEYORACLE.SECURITY.ID.ENCRYPTION.ORACLE.SECURITY.KB.ENCRYPTION.Trusted Certificates:
Since I have the missing key, the next step is merging it into the CDB wallet.
At this stage, we need a wallet merge command. Although Jimmy’s blog post uses the orapki wallet merge -wallet command, there is actually no merge option available in orapki.
For this reason, we used the command provided below instead:
SQL> administer KEY management MERGE keystore '/u01/app/oracle/myluckywallet/tde/'into existing keystore '/u01/app/oracle/mycdbwalet/MYNEWCDB/wallet/tde' identified BY "mypass" WITH BACKUP using 'before_merge';
If you are using an auto-login keystore, you do not need to know or specify the password for the source wallet in the upper clause.
The first directory refers to the wallet location that contains the missing encryption key, while the second directory is the existing wallet location into which the key will be merged. We need to know the password of the target CDB wallet.
What drove me crazy and cost me hours :
After the merge command completed successfully, I was confident that the missing key had been found and correctly imported. The operation finished without errors, so everything looked fine from a first glance.
To verify the result, I checked whether the merged wallet actually contained the missing key by running:
[oracle@myserver ~]$ orapki wallet display -wallet '/u01/app/oracle/mycdbwalet/MYNEWCDB/wallet/tde'
However, the expected key was not shown in the output.
At this point, what I initially missed was an important detail: the orapki wallet display command often relies on the auto-login keystore (.sso) to present wallet contents. Since the underlying wallet had changed after the merge, the auto-login wallet needed to be recreated to reflect the updated keys.
Without recreating the auto-login keystore, the display output did not reflect the actual merged state of the wallet, which led to confusion even though the merge itself had succeeded.
Now to recreate autologin keystore:
SQL> ADMINISTER KEY MANAGEMENT CREATE AUTO_LOGIN KEYSTOREFROM KEYSTORE '/u01/app/oracle/mycdbwalet/MYNEWCDB/wallet/tde'IDENTIFIED BY "mypass";
After recreating the .sso file, you may check and see the missing key is available in the target wallet.
Now when I retried the openning the pluggable database, same violation still exists. Actually the required step is already mentioned in the alert.log,
MYTESTPDB(3): ALTER PLUGGABLE DATABASE OPEN detects that an encrypted tablespace has been restored but the master key has not been set for the database, or the database has been flashback’ed prior to first set key of the master key (pdb 3).
MYTESTPDB(3): Resetting the master key is required. Please execute ADMINISTER KEY MANAGEMENT SET ENCRYPTION KEY command, or select the latest master key from V$ENCRYPTION_KEYS and execute ADMINISTER KEY MANAGEMENT USE KEY <key_id> command if the SET ENCRYPTION KEY command cannot find and decide the master key to use.
we need to say pdb to use this missing key
SQL> alter session set container=MYTESTPDB;SQL> administer key management use key 'ARfZOD6QcF+Sv+HlNAy5LQPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' force keystore identified by "mypass" ;
Although I had already set the key, the PDB_PLUG_IN_VIOLATIONS entry was still present. When I queried V$ENCRYPTION_KEYS inside the PDB, the key was still missing. Interestingly, the key was visible only when I queried the view from CDB$ROOT.
At that stage, still full of anxiety, I finally identified the missing piece of the puzzle: the key had not been propagated to the PDB.
What was required was simply to export the encryption key from CDB$ROOT and import it into the PDB. Once this was done, the violation disappeared and the PDB transitioned out of the restricted mode.
SQL> alter session set container=MYTESTPDB;SQL> administer KEY management export keys WITH secret "mysecretjusttohash" TO '/u01/app/oracle/exported_key' force keystore identified BY "mypass";SQL> administer KEY management import keys WITH secret "mysecretjusttohash" FROM '/u01/app/oracle/exported_key' force keystore identified BY "mypass" with backup using 'before_import';
While trying to solve it, I honestly felt a bit foolish. I was basically exporting the key from the CDB wallet and importing it right back into the same place, like walking in a maze.
After everything was finally resolved, I later came across Daniel’s post “How To Upgrade An Encrypted Oracle Database and Convert to PDB”, and even the same question had already been asked by him “Why Do I Need to Export and Import?” in there. Although our blogs contents may look a little bit similar, I have tried to explain all the steps with the errors faced and more clarification.
Hope it helps.


Leave your comment