Encrypting a Database Never Finishes

There is plenty of legislation and regulation in place these days that strongly suggest encrypting a database. In SQL Server, we have the ability to comply with these regulations in a couple of different ways.  We can choose to encrypt at the column level or we can choose to encrypt the entire database using TDE (transparent data encryption).

Given these opportunities and methods of encrypting a database and protecting data, some clients will want to comply with the regulation and move forward with encryption.  Every now and again, the client might run into something they can enable themselves.  TDE happens to be one of those things.  Enabling TDE is pretty easy.  Sometimes things run very smoothly and sometimes there is a problem.  Unfortunately, the problem may not always be immediately evident.

This is one of those times.  If you enable a setting in a database, you would expect it to be in effect and to be working.  Sometimes, with TDE, that change doesn’t take effect. What actually happens is the switch is thrown, the database tries to comply, but something prevents the database from completing the directive it was just given.  As luck would have it, I had the opportunity to assist recently with such a case.

Infinitely Encrypting a Database

Before diving too far down into the problem, let’s take a look at how we can gauge and measure the encryption progress.  Microsoft has provided a dynamic management view to see and track the status and progress of encryption that we have tried to enable.  This view is sys.dm_database_encryption_keys.  Within that view there are a few important and useful fields.  One field is the encryption thumbprint, another is the encryption state, and another tells us the percent that has been completed.

With a little tsql from the toolbelt, we can pull back the essential information to monitor the encryption progress.

SELECT DB_NAME(ek.database_id) AS DBName,ek.percent_complete,ek.modify_date
	,ek.encryption_state
	,CASE ek.encryption_state
		WHEN 0 THEN 'No database encryption key present, no encryption'
		WHEN 1 THEN 'Unencrypted'
		WHEN 2 THEN 'Encryption in progress'
		WHEN 3 THEN 'Encrypted'
		WHEN 4 THEN 'Key change in progress'
		WHEN 5 THEN 'Decryption in progress'
		WHEN 6 THEN 'Protection change in progress'
		END AS Encryption_State_desc
	FROM sys.dm_database_encryption_keys ek;

You’ll notice that I have a case statement in there to transform the encryption_state values into a human friendly form.  Sadly, the human friendly values are not stored in the database and are only documented in MSDN / BOL.

Now on to the problem at hand—the encryption that starts but never ends.  Given that I have a database named “Published”, I can enable encryption with the following script.

ALTER DATABASE Published
SET ENCRYPTION ON;

After issuing the encryption command, I can then pull up my “status” script and see how things are rolling.

encrypting a database

In this example, and for the sake of this article, this database will remain at 0% complete for days and months if allowed to remain that way.  Notice that it still thinks it is progressing, but nothing is actually getting done.  This kind of result can also be seen after a database reaches 99% complete.  At some point, something occurred that caused grief for the encrypting process.  As soon as that happens, the report will revert back to 0% complete and just stall indefinitely.  The types of things that can cause this vary from corruption to index rebuilds occurring at the same time as the attempt at encryption.

When a stall such as this occurs, the fix could be as simple as restarting the encryption with the statement previously used.  Here that is again (bearing in mind to substitute the appropriate database name for the one I used in this demo):

ALTER DATABASE Published
SET ENCRYPTION ON;

In some cases, that won’t work.  And sometimes you just may want to proceed very cautiously.  In those events, you can get your database back on track to being encrypted by using the following:

DBCC TRACEON(5004)
GO
DBCC TRACEOFF(5004)
GO
ALTER DATABASE Published
SET ENCRYPTION ON;

The use of this trace flag forces the page scan, used to encrypt the database, to stop (even though it already appears to have stopped).

If I check my encryption status again, I should see the percentages growing until 100% is achieved and eventually the state that declares the database as being encrypted.  This is demonstrated in the following three screenshots.

And finally we have an encrypted database.

Conclusion

Transparent Data Encryption is useful in helping get a database into compliance with several regulations.  It is also fairly easy to implement.  Occasionally, it may only appear to have completed successfully.  When the SQL statement completes, TDE is not entirely in place.  Though it is “enabled”, it may still be waiting for the encryption phase to complete.  Once the statement to encrypt the database has been issued, it is important to follow up with a bit of monitoring to ensure the database progresses to the encrypted state.  If that doesn’t happen, you could end up in a state where you think the database is encrypted and it actually just stalled.

Please share this

This Post Has 9 Comments

  1. Ayman El-Ghazali

    This problem screwed me over before, glad to know there is a solution and I hope to never face this problem again!!!

    1. Jason Brimhall

      Thanks Ayman. Too bad we couldn’t have gotten this out there sooner for you. 😉

  2. Alan Schuele

    I am having a similar problem while decrypting a database. I am stuck in “decryption in progress” It is the same trace flag number 5004. I tried but it did not work. Thanks!

    1. Jason Brimhall

      Did you try to set the TF on and then off?
      DBCC TRACEON(5004)
      GO
      DBCC TRACEOFF(5004)
      GO

  3. tom c

    I’m having the same issue as Alan with a database stuck in “decryption in progress” after an ALTER DATABASE ENCRYPTION KEY command on database in an availability group

    Tried the DBCC TRACEON/OFF(5004) trick, followed by an ALTER DATABASE SET ENCRYPTION OFF, but it said was encryption was already in process and it failed. Hoping for solution that won’t involve bouncing server. Any thoughts/suggestions?

    1. Jason Brimhall

      Are you able to get a percent complete from the query posted in the article?

  4. tom c

    It was stuck at 71%. Turns out it was an undetected deadlock between TDE and the ghost cleanup process, which is a suspected SQL Server defect. Resolution was to enable TF661 and bounce the instance. Once TDE cleared up, clear the trace flag. That was a fun one.

  5. Jason Brimhall

    Thanks for the feedback. I will see what we can do about a follow-up to that effect.

  6. Jay Squared Galdores

    Hi, i experience alao the stuck of percentage upon encryption. Done using dbcc trace on/off and still percentage completion to 0. Please help me i cant use my database inserting and alter. Thank yoh.

Leave a Reply

Related Articles

A toy machine and a microphone on a table Description automatically generated

The Right Tool for the Right Job

I’m looking forward to 2024. From many perspectives, I think we are going to see great advancements, including in technology, that on one hand will make our lives easier, but also make our decisions a bit harder.

Read More »