Certificate Services Did Not Start on a Sub CA…

Hi Internet friends!  I recently came across a two-tier PKI infrastructure (Enterprise-style, with offline root) that was set up for a customer who was transitioning to a brand new AD Forest.  The customer stated the CAs were working just fine when initially built, and had the validation documentation to prove it.

However, a couple months later, the customer was receiving errors when trying to generate a certificate from the subordinate CA for a new application infrastructure, and they asked for help.  They saw this error in Event Viewer:

Event ID 100: Active Directory Certificate Services did not start: Could not load or verify the current CA certificate.  <subCA certificate name>  The revocation function was unable to check revocation because the revocation server was offline. 0x80092013 (-2146885613 CRYPT_E_REVOCATION_OFFLINE).

/sites/default/files/20140625/1-CaError.png

Odd that it worked at implementation, but suddenly stopped working.  It was time to check things out and review the implementation.

The first thing I noticed was that the Active Directory Certificate Services service (certsvc) would not start.  When I tried it from the Certification Authority GUI I saw the error message shown at left.

You’ll note that the GUI message is nearly identical to the Event ID 100 message.  I simply mention this so if you do see the message in the GUI, you don’t need to run to Event Viewer; you’ve got the same issue I experienced at the customer site.

Web searching was only slightly helpful and put me in the ballpark for the fix, but it didn’t bring me all the way home.  And if you simply want my quick steps on how I corrected the issue, here is what I did:

  1. Powered up the offline root CA
  2. Renewed the Subordinate CA certificate with the Root CA and re-installed it on the Subordinate CA
  3. Regenerated the Root CA CRL and copied it to the correct location on the Subordinate CA
  4. Started the AD CS service on CA1, the Subordinate CA.

/sites/default/files/20140625/2-CertDeets.png

But if you want more detail on what I discovered, here’s the meat…

First off, the Root CA CRL was set to expire in just seven days.  That’s not going to be good.  That right there prevents the certsvc service from starting after the Root CA Certificate Revocation List (CRL) expires.  The service depends on finding Root CA CRL.  If it is expired – or can’t find it – the service will not start.

Simply regenerating that and replacing it on the Subordinate CA – after adjusting the CRL Publication interval to 1 Year – was the first thing I tried, but it didn’t help.  This led me to investigate if the Subordinate CA could even find the Root CA CRL. 

I opened the Subordinate CA certificate, clicked the Details tab, and checked the value in the CRL Distribution Points entry, shown here at right.

That’s where the light bulbs started to get bright.  The server was named ca1.domain.com, but they had their PKI IIS set up with the URL pki.domain.com/pki.

/sites/default/files/20140625/3-CaRootExtensions.png

I checked the CRL Distribution Point settings on the Root CA and the Subordinate CA.  Ah ha!  They were not matching what was in the Subordinate CA cert.

Now take a look at the Root CA CRL CDP Settings in the Properties page at left.  You’ll see that this is set to the URL I mentioned before, pki.domain.com/pki – which is *not* what is in the Subordinate CA CRL Distribution Points property of the certificate!

The fix was now pretty apparent.  All I needed to do was renew the Subordinate CA certificate and replace it on CA1.

Take a look below at the CRL Distribution Point property on the new Subordinate CA cert and you’ll see it now matches what is in the Root CA settings.

/sites/default/files/20140625/4-CertDeets.png

From there it was just adjusting the Root CA CRL publication interval in the Certification Authority MMC by right clicking Revoked Certificates, selecting Properties, then setting it according to Microsoft Best Practices of 1 Year, as shown here.

Then, I right clicked on Revoked Certificates, selected All Tasks, Publish, and re-published the CRL and copied it to the /pki folder on the Subordinate CA Server.

Viola!  The services now started on CA1, the Subordinate CA, and everything worked as expected.

Now it’s true that this does mean that the Root CA must be powered up annually so the CRL can be regenerated and copied, but there is no getting around that. 

Yes, of course you can set the CRL publication interval to be longer than a year; but as per best practices, you should set that to expire in the least amount of time that is tolerable.  And in this customer’s case, the recommendation of each year was suitable and appropriate.

/sites/default/files/20140625/5-RevokedPubParams.png

Firing up the Root CA and doing this annually isn’t a big deal in my world, hence that recommendation.

In the end, with the certificate service running and the CRLs fixed, the customer was able to mint the certificates necessary for the new application, and I made an appointment with the customer in my calendar for just shy of a year from now…

I hope that helps someone else out there!

2017-07-27T00:01:02+00:00 June 26th, 2014|Uncategorized|

About the Author:


Fatal error: Uncaught exception 'GuzzleHttp\Exception\ClientException' with message 'Client error: `POST https://dc.services.visualstudio.com/v2/track` resulted in a `400 Invalid instrumentation key` response: {"itemsReceived":1,"itemsAccepted":0,"errors":[{"index":0,"statusCode":400,"message":"Invalid instrumentation key"}]} ' in /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113 Stack trace: #0 /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/guzzle/src/Middleware.php(66): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response)) #1 /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/promises/src/Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response)) #2 /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/promises/src/Promise.php(156): GuzzleHttp\Promi in /home/coretek/public_html/wp-content/plugins/application-insights/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php on line 113