Debugging custom policy exceptions in Azure AD B2C

Image of generic browser error
Error by Graphic Enginer from the Noun Project

Exceptions and errors in B2C when using custom policies are logged using Application Insights.

As I have encountered exceptions, I have documented how I have searched for the actual cause.

Note that these are the error messages displayed in the browser.

I will keep adding cases to this post as I encounter new ones.

I have documented them by their error message “type”.


In the Application Insights page, click on “Logs”.

Menu line showing the “Logs” tab

The two queries I use are “exceptions” and “traces”.

Image showing “exceptions” and “traces” in the LHS menu

Double-click them to put the query in the query window and then click “Run”.

Message type 1

The page cannot be displayed because an internal server error has occurred.

This is not very useful!

Use the “exceptions” query.

Image showing results of the “exceptions” query

Sort by time descending using the time range field.

The exception is contained in the “outerMessage” e.g.

Exception Message:Output claim type “mail” specified in the technical profile with id “EmailVerifyOnSignIn” in policy “B2C_1A_Policy” of tenant “” does not specify a UserInputType or a DefaultValue, and is not retrieved from a ValidationTechnicalProfile either., Exception Type:InvalidDefinitionException, CorrelationID:9b…….12

To see this easily:

Click in the “outerMessage” box and then hit “Enter”.

Image showing expanded outerMessage box

Message type 2

Image showing B2C “an exception has ocurred”

Use the “exceptions” query e.g.

Exception Message:A Claim of ClaimType with id “mail” was not found, which is required by the ClaimsTransformationImpl of Type “Microsoft.Cpim.Data.Transformations.FormatStringClaimTransformation” for TransformationMethod “FormatStringClaim” referenced by the ClaimsTransformation with id “CopyMailToReadOnly” in policy “x” of tenant “y”., Exception Type:PolicyException, CorrelationID:fd3…806

If “exceptions” shows lots of hits, narrow it down by the timestamp or the correlation ID both of which are in the error message.

You can search by correlation ID but be aware that there will be lots — it’s in every step.

Image showing “traces | where message contains “correlation ID” and message contains “Exception””

Or sort to get the latest date at the top and then use the “Export to CSV” option.

Image showing Excel spreadsheet with “Column B” expanded

Expand column B (the “message” column) and cursor down until you see the error.

Message type 3

Image showing B2C exception message: “An error occurred while processing the request”

Use the “exceptions” query e.g.

Exception Message:An error occurred while processing the request. Please contact administrator of the site you are trying to access., Exception Type:PolicyException, CorrelationID:e9d32c32-a172–4ae6-af24–7ac30c03370b

Which is pretty useless! The exception simply tells you there was an error 😢

In this case, run “traces”, and sort so that the latest trace is at the top.

Then click the trace so you see the box:

Image showing timestamp column selected

then “Export to CSV — all columns”.

Image showing Excel spreadsheet with “Column B” expanded

Expand column B (the “message” column) and cursor down until you see the error e.g.

“Exception”: {

“Kind”: “Handled”,

“HResult”: “80131500”,

“Message”: “A claim could not be found for lookup claim with id \”signInName\” defined in technical profile with id \”AAD-UserReadUsingUserName\” policy \”policy”\” of tenant \”\”.”,


Note: I actually find it easier to open the downloaded .csv file with something like Notepad++ and then search for the date / time and then for the error.

As above, you can filter on time:

Image showing filtering using the “Time range” box

Or you can use the query language:


| where timestamp > ago(30m)

i.e. only show exceptions in the last 30 minutes


| where timestamp > ago(1h)

i.e. only show traces in the last hour

or something like:


| where timestamp > ago(2h)

and message contains “Exception”

You can comment out lines by using “//”



| where timestamp > ago(2h)

// and message contains “Exception”

If you want to see a specific time e.g. “exceptions” shows:

Image showing list of exceptions

Then search for the exact time.

Image showing query: “exceptions | where timestamp == “9/13/2021, 11:59:42.346 PM” “

If you want to see the actual exception message:


| extend exp = extract(@”^(.+)Exception”, 1, outerMessage)

Image showing “exceptions | extend exp = extract(@”^(.+)Exception”, 1, outerMessage)”

And make the “exp” column bigger.


There is also some logging you can do e.g. the Woodgrove sample has:

<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchange Id="UserJourneyContextExchange" TechnicalProfileReferenceId="UserJourneyContext"/>


<TechnicalProfile Id="UserJourneyContext">
<DisplayName>User Journey Context</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.UserJourneyContextProvider, Web.TPEngine, Version=, Culture=neutral, PublicKeyToken=null"/>
<OutputClaim ClaimTypeReferenceId="correlationId" PartnerClaimType="CorrelationId"/>
<OutputClaim ClaimTypeReferenceId="clientIpAddress" PartnerClaimType="IP-Address"/>

You can also track user behaviour.

“To enable custom event logs, add an Application Insights technical profile. In the technical profile, you define the Application Insights instrumentation key, the event name, and the claims to record. To post an event, add the technical profile as an orchestration step in a user journey.”

Hope this helps 😃

All good!



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store