I am experiencing persistent schema validation errors when uploading my Azure AD B2C custom policy, specifically related to the <ClaimsTransformations>
section. The error message is not always the same, but it typically states:
The element 'ClaimsTransformation' in namespace 'http://schemas.microsoft.com/online/cpim/schemas/2013/06' has invalid child element 'InputClaims' in namespace 'http://schemas.microsoft.com/online/cpim/schemas/2013/06'. List of possible elements expected: 'OutputClaims' in namespace 'http://schemas.microsoft.com/online/cpim/schemas/2013/06'.**
Key Details:
The error sometimes points to different lines, but always references <InputClaims>
as an invalid child for certain transformation methods.
I have verified that for transformation methods like CopyClaim
, FormatStringMultipleClaims
, and BuildUri
, I am using <InputClaims>
and <OutputClaims>
as per documentation.
For methods like CreateOtpSecret
, CreateStringClaim
, and FormatStringClaim
, I am only using <OutputClaims>
(and <InputParameters>
if needed), with no <InputClaims>
.
Despite this, the error persists and sometimes appears even when the XML is schema-compliant.
What I’ve Tried:
Double-checked all <ClaimsTransformation>
blocks for correct usage of <InputClaims>
, <OutputClaims>
, and <InputParameters>
.
Removed any <InputClaim>
elements from transformation methods that do not support them.
Validated the XML structure and ensured there are no duplicate or misplaced elements.
<!-- ===== Transformations ===== -->
<ClaimsTransformations>
<ClaimsTransformation Id="CopyObjectIdToUserId"
TransformationMethod="CopyClaim">
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="objectId"
TransformationClaimType="inputClaim" />
<OutputClaim ClaimTypeReferenceId="userId"
TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
<ClaimsTransformation Id="CopyInviteTokenToSecretKey"
TransformationMethod="CopyClaim">
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="extension_d370edc869fd4e23ba22efa407bd8935_InviteToken"
TransformationClaimType="inputClaim" />
<OutputClaim ClaimTypeReferenceId="secretKey"
TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
<ClaimsTransformation Id="CreateIssuer"
TransformationMethod="FormatStringClaim">
<InputParameters>
<InputParameter Id="stringFormat"
DataType="string"
Value="{0}" />
</InputParameters>
<InputClaims>
<InputClaim ClaimTypeReferenceId="totpIssuer"
TransformationClaimType="inputClaim" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="totpIdentifier"
TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
<ClaimsTransformation Id="FormatTotpLabel"
TransformationMethod="FormatStringMultipleClaims">
<InputParameters>
<InputParameter Id="stringFormat"
DataType="string"
Value="{0}:{1}" />
</InputParameters>
<InputClaims>
<InputClaim ClaimTypeReferenceId="totpIdentifier"
TransformationClaimType="inputClaim1" />
<InputClaim ClaimTypeReferenceId="email"
TransformationClaimType="inputClaim2" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="totpLabel"
TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
<ClaimsTransformation Id="CreateQrCodeUri"
TransformationMethod="BuildUri">
<InputParameters>
<InputParameter Id="scheme"
DataType="string"
Value="otpauth" />
<InputParameter Id="path"
DataType="string"
Value="totp" />
</InputParameters>
<InputClaims>
<InputClaim ClaimTypeReferenceId="totpLabel"
TransformationClaimType="label" />
<InputClaim ClaimTypeReferenceId="secretKey"
TransformationClaimType="secret" />
<InputClaim ClaimTypeReferenceId="totpIssuer"
TransformationClaimType="issuer" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="qrCodeContent"
TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
</ClaimsTransformations>
<!-- ===== Content definitions ===== -->
For all ClaimsTransformation
definitions the InputClaims
element must come before InputParameters
which comes before OutputClaims
(doc example).
So, for example:
<ClaimsTransformation Id="CreateQrCodeUri" TransformationMethod="BuildUri">
<InputClaims>
<InputClaim ClaimTypeReferenceId="totpLabel" TransformationClaimType="label" />
<InputClaim ClaimTypeReferenceId="secretKey" TransformationClaimType="secret" />
<InputClaim ClaimTypeReferenceId="totpIssuer" TransformationClaimType="issuer" />
</InputClaims>
<InputParameters>
<InputParameter Id="scheme" DataType="string"Value="otpauth" />
<InputParameter Id="path" DataType="string" Value="totp" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="qrCodeContent"TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>