Your data. Anywhere you go.

New Relic for iOS or Android

Download on the App Store    Android App on Google play

New Relic Insights App for iOS

Download on the App Store

Learn more

Close icon

Relic Solution: Using Synthetics to Monitor SSL Expiration



Hi Stefan, I have set the API key from Insights and I have the admin permission.

Verified the license key and the account ID are correct, but still getting the error.


Without further information on your script, @yograj.patel, I cannot assist. Perhaps @RyanVeitch can assist in the meantime?


var request = require(‘request’),
assert = require(‘assert’),
Q = require(‘q’);

What is the URL that you want to check?

var urlsToMonitor = [‘’,‘’,'’];

var licenseKey = ‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxx’;
var accountId = ‘xxxx15’;

function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;

function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return Math.round((treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay);

function insertInsightsEvent(urlMonitored, certificateIssuer, daysToExpiration, expirationMilliseconds){
var options = {
uri: ‘’+accountId+’/events’,
body: ‘[{“eventType”:“SSLCertificateCheck”,“Url”:"’+urlMonitored+’",“Issuer”:"’+certificateIssuer+’",“DaysToExpiration”:’+daysToExpiration+’, “ExpirationDate”:’+expirationMilliseconds+’}]’,
‘X-Insert-Key’: licenseKey,
‘Content-Type’: ‘application/json’
console.log("Posting event for: “+urlMonitored);, function(error,response, body){
console.log(response.statusCode + " status code”);
assert.ok(response.statusCode == 200, ‘Expected 200 OK response’);
var info = JSON.parse(body);
assert.ok(info.success == true, 'Expected True results in Response Body, result was ’ + info.success);
console.log(“SSL cert check completed successfully”);

function processSite(urlToMonitor)
//var deferred = Q.defer();
console.log('Preparing to monitor '+urlToMonitor);

var theRequestObject = request({
url: urlToMonitor,
method: ‘HEAD’,
gzip: true,
followRedirect: false,
followAllRedirects: false

function(res) {
var certDetails = (res.req.connection.getPeerCertificate());
var currentDate = new Date();
var certExpirationDate = new Date(certDetails.valid_to);
var certificateIssuer = certDetails.issuer.O;
var daysToExpiration = daysBetween(currentDate, certExpirationDate);
var certificateIssuer = certDetails.issuer.O;
console.log('This certificate was issued by '+certificateIssuer, ‘’);
console.log('This SSL certificate will expire on ‘+certExpirationDate, ‘’);
console.log(’**** Date at time of testing: ‘+currentDate);
console.log(’**** Days to expiration: '+daysToExpiration);
console.log("Creating event for: "+urlToMonitor);
insertInsightsEvent(urlToMonitor, certificateIssuer, daysToExpiration, certExpirationDate.getTime());

for(var i=0; i< urlsToMonitor.length; i++)
var urlToMonitor = urlsToMonitor[i];


It looks like some of your script is missing as I pasted yours in a new script and there are several errors displayed for undefined objects such as theRequestObject.

I would suggest, as you have removed the promises, that you output the parameters for insertInsightsEvent to the console so you can verify they are being passed correctly.


@stefan_garnham I have used the same query which you have provided in the above chat, updated my api key under license key and updated the account ID (****115/integrations?page=api_keys ) taken from the masked data.

But getting forbidden error.

Preparing to monitor
Preparing to monitor
This certificate was issued by Google Trust Services
This SSL certificate will expire on Tue Aug 28 2018 11:32:00 GMT+0000 (UTC)
**** Date at time of testing: Tue Jul 03 2018 13:57:53 GMT+0000 (UTC)
**** Days to expiration: 56
Creating event for:
Posting event for:
403 status code

AssertionError: Expected 200 OK response
at Request.eval [as _callback] (eval at (/opt/runtimes/2.0.0/modules/synthetics-runner/lib/job-resource/index.js:76:19), :40:14)
at Request.self.callback (/opt/runtimes/2.0.0/node_modules/request/request.js:198:22)
at Request.emit (events.js:110:17)
at Request. (/opt/runtimes/2.0.0/node_modules/request/request.js:1057:14)
at Request.emit (events.js:129:20)
at IncomingMessage. (/opt/runtimes/2.0.0/node_modules/request/request.js:1003:12)
at IncomingMessage.emit (events.js:129:20)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)

Not sure If i’m doing something wrong.

And I dont see the data in Insights as well.


It sounds as though you do not have the correct account and API key, or you just do not have permissions to create the data. It seems as though you will need some support from New Relic staff. @RyanVeitch can assist with that.


@stefan_garnham Thanks for your help here, and for pinging me on this.

@yograj.patel -

The 403 Forbidden error is happening as we post the events to Insights. The Insights Insert API will return 403s when it cannot authenticate the API key, I replicated this by ensuring my account had no access to insights (Insights None subscription), I still used the correct API key & account ID…

When I enabled the appropriate subscription for my account the monitor ran fine…

In testing this, I also substituted a false API key, and got the same 403 error, fixing the API key fixed the error.

So this points to two possibilities;

  • Wrong API Key.
  • Most likely - I opened your account and I can’t see any insert API key listed in the SSL cert test script I can find. Could you PM me with the API key you are using and can I have your permission to test the script in your account myself?
  • Invalid subscription.
  • This makes a little less sense to me, I can see from your account that you have Insights Pro, additionally I asked our engineers to look at your account in the DB and we see the appropriate subscriptions there.

Like I mentioned, my thoughts currently are that this is an API key issue. If possible, please do PM me the API key (or link to it) so I can run a test here to validate the behaviour you are seeing.

If we can replicate this with that information we’ll get this escalated further for investigation.


@RyanVeitch I have provided the api key details and the account ID info. Please verify and assist me.


@yograj.patel - Thanks for sending that over. That looks like your Admin account API key.

For the Insights Insert API you’ll need a different key.

There are 2 Insights specific API keys, 1 for inserting data and 1 for querying. In this case you’ll need an Insert key which you can find here:

Let me know if updating that key helps :smiley:


Thanks Ryan, it worked.


Thanks! That worked. I’ve tweaked it a bit to generate different error messages but in a nutshell it works!


@RyanVeitch Hello there, I’m new to the community and having the same “Forbidden 403 status code” for the SSL Cert check. Could you walk me thru where to get the API keys for use? Thanks in advance


Hey @markangelo.lineses - you got it! Those failures were due to the Insights API key being incorrect. There are 2 types of insights API Keys though - Insert Data, or Query Data.

You’ll need an Insert Key, which you can create here:{your_account_id}/manage/api_keys

Just fill in your account ID to that URL. Note that if you can’t create a key there, you’ll need to reach out to an admin on your account with the appropriate permissions. :slight_smile:


it now worked. thank you


You got it! Glad you were able to get this working :smiley:


The SSL expiry check was working fine till somedays back, but getting the below error.[start]=1553526791.823&tw[end]=1553528591.823

Error: Parse Error
at Error (native)
at TLSSocket.socketOnData (_http_client.js:317:20)
at TLSSocket.emit (events.js:129:20)
at readableAddChunk (_stream_readable.js:163:16)
at TLSSocket.Readable.push (_stream_readable.js:126:10)
at TCP.onread (net.js:540:20)


The SSL expiry check was working fine till somedays back, but getting the below error.[start]=1553526791.823&tw[end]=1553528591.823

Error: Parse Error
at Error (native)
at TLSSocket.socketOnData (_http_client.js:317:20)
at TLSSocket.emit (events.js:129:20)
at readableAddChunk (_stream_readable.js:163:16)
at TLSSocket.Readable.push (_stream_readable.js:126:10)
at TCP.onread (net.js:540:20)


Hey @yograj.patel - That’s strange. The SSL Expiration script is still working for me. The only difference I can think of is that I’m running mine on different URLs than you are.
It’s possible that a response from one or more your websites is causing this parse error.

I would recommend removing an array of URLs and trying to validate the script with one URL at a time. This will hopefully reveal if one of the URLs is problematic.


I am getting the issue when monitoring the url which is a major application url


Hi @yograj.patel - Sorry for the delay here, I had a colleague look at this as well and below is what we came up with;

Currently there is no handling for the possibility of an error in the callback, so we’d recommend that you add a few lines to do that, and you may get a more relevant error, but seems like the response data returned from that request was in an unexpected format / couldn’t be parsed correctly.
It’s hard to say if its on the Insights POST, as we see you are asynchronously firing off requests to multiple endpoints, though, in any case it’s recommended that you add error handling to the processSite function

Let us know if you can try that out. :smiley: