Fixing Client secret expiration errors for Provider hosted add-in on SharePoint Online

Published May 01 2019 04:04 PM 705 Views

First published on TECHNET on Jan 18, 2017
This post is a contribution from Mustaq Patel, an engineer with the SharePoint Developer Support team

You have a  Provider hosted add-in for SharePoint Online hosted in Azure or public facing IIS Server and it fails due to ClientSecret expiry. You will see the below error

Invalid issuer or signature.

at Microsoft.IdentityModel.S2S.Tokens.JsonWebSecurityTokenHandler.VerifySignature(String signingInput, String signature, String algorithm, SecurityToken signingToken)

at Microsoft.IdentityModel.S2S.Tokens.JsonWebSecurityTokenHandler.ReadTokenCore(String token, Boolean isActorToken)

You generated new clientSecret and followed article that to replace old clientsecret but the app is still failing.


First to note that applies only to the ClientSecret that are not yet expired but about to expire. Since it takes 24 hours to get the ClientSecret effective, having SecondaryClientSecret (which is still unexpired) gives the app a fallback mechanism if the new ClientSecret is not effective yet.

The recommendation is that if the clientsecret is already expired and generating new clientsecret and after waiting for 24 hours still App fails with above error, it is time to clean those lingering secrets for a particular ClientId, generate a new clientSecret. Below steps will walk you through that process.

    1. Identify the ClientId for which ClientSecret is expired. You can find the clientId in Site App Permissions if the app is still installed. If not, you can find it in the web.config of the remote web application. say ClientId is 29b6b386-62a6-45c7-beda-abbaea6eecf2


    1. Connect to MSOnline using tenant admin user with below powershell in SharePoint 2013 powershell

import-module MSOnline

$msolcred = get-credential

connect-msolservice -credential $msolcred

    1. Get ServicePrincipals and keys. Printing $keys will give 3 records. While running this script if you get ReturnKeyValue without any output, hit enter on powershell prompt and 3 keys will be printed.

$clientId = "29b6b386-62a6-45c7-beda-abbaea6eecf2"

$keys = Get-MsolServicePrincipalCredential -AppPrincipalId $clientId


    1. Run the below command. Replace KeyId1, KeyId2 and KeyId3 from previous output.

Remove-MsolServicePrincipalCredential -KeyIds @("KeyId1"," KeyId2"," KeyId3") -AppPrincipalId $clientId

    1. Confirm all the keys are deleted for the given ClientId by running #3

    1. Generate new ClientSecret for this ClientId. Please note it uses ClientId from #1. The New ClientSecret generated will have a validity for 3 years.

$bytes = New-Object Byte[] 32

$rand = [System.Security.Cryptography.RandomNumberGenerator]::Create()



$newClientSecret = [System.Convert]::ToBase64String($bytes)

$dtStart = [System.DateTime]::Now

$dtEnd = $dtStart.AddYears(3)

New-MsolServicePrincipalCredential -AppPrincipalId $clientId -Type Symmetric -Usage Sign -Value $newClientSecret -StartDate $dtStart –EndDate $dtEnd

New-MsolServicePrincipalCredential -AppPrincipalId $clientId -Type Symmetric -Usage Verify -Value $newClientSecret -StartDate $dtStart –EndDate $dtEnd

New-MsolServicePrincipalCredential -AppPrincipalId $clientId -Type Password -Usage Verify -Value $newClientSecret -StartDate $dtStart –EndDate $dtEnd


    1. The output is the $newClientSecret. Copy it and replace the old ClientSecret with this one. Make sure ClientId in there is the same we are using throughout. Please note we don’t need SecondaryClientSecret appsettings in here.

Try browsing the app and see if it works, we have seen varied results, most of the time it works, if not wait for 24 hours to propagate ClientSecret to SPO.


Adding links to sample scripts

Version history
Last update:
‎Sep 01 2020 03:06 PM
Updated by: