XML Validation in APIM policy not working correctly

Johnson, Dana 20 Reputation points
2026-07-31T12:43:27.26+00:00

Gents, I'm trying to validate an XML document against an XSD schema using the following:

<validate-content

unspecified-content-type-action="prevent"

max-size="1048576"

size-exceeded-action="prevent"

errors-variable-name="validationErrors">

<content

    type="application/xml"

    validate-as="xml"

     schema-id="MySchema"

    action="prevent" />
</validate-content>

The Validate Content does not work no matter what I add or change in the properties

Any suggestions would be greatly appreciated

Azure API Management
Azure API Management

An Azure service that provides a hybrid, multi-cloud management platform for APIs.

0 comments No comments

Answer accepted by question author
Rakesh Mishra 11,340 Reputation points Microsoft External Staff Moderator
2026-07-31T14:25:49.6266667+00:00

Hello @Johnson, Dana ,

Welcome to the Microsoft Q&A Platform! Thank you for asking your question here.

Thanks for sharing the test payload and the exact error message in Private message. Your XML payload is perfectly valid for the CAP v1.2 specification.

The specific error you are encountering - "Unspecified content type application/xml is not allowed." actually occurs before the XML content is validated against your schema. It means that the validate-content policy is blocking the request because your API operation's definition (the "Frontend" contract) has not been configured to expect application/xml as an incoming request format.

Because your policy is set to unspecified-content-type-action="prevent", API Management strictly checks the API definition to see if application/xml is declared.

According to the official Azure API Management validate-content documentation:

unspecified-content-type-action: Action to perform for requests or responses with a content type that isn't defined in the API schema.

To resolve this via the JSON Editor:

  1. In the Design tab for your Create Alert operation, click the pencil icon on the Frontend block.
  2. In the JSON editor, locate your post operation (around the "operationId": line).
  3. Insert a requestBody definition right before the "responses" block to explicitly allow application/xml and link your CAP1-2 schema:
       "requestBody": {
         "content": {
           "application/xml": {
             "schema": {
               "$ref": "#/components/schemas/CAP1-2"
             }
           }
         }
       },
    
  4. Click Save at the bottom of the screen.

Once saved, the validate-content policy will recognize the payload content type and successfully validate it against your CAP schema.

Let me know if this resolves the issue.

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Johnson, Dana 20 Reputation points
    2026-08-10T14:02:25.84+00:00

    The issue is that I'm getting 400s for everything
    {

    "statusCode": 400,
    
    "message": "Unspecified content type application/xml is not allowed."
    

    }
    My Payload used , and i still get a 400

    <alert xmlns="urn:oasis:names:tc:emergency:cap:1.2"> <identifier>50ab1576-e16b-4e8d-8aba-84c1ab83c136</identifier> <sender>******@gmail.com</sender> <sent>2026-06-03T12:57:08-05:00</sent> <status>Test</status> <msgType>Alert</msgType> <scope>Public</scope> <info> <language>en-US</language> <category>Met</category> <event>NUW</event> <responseType>Execute</responseType> <urgency>Immediate</urgency> <severity>Extreme</severity> <certainty>Observed</certainty> <senderName>Dana's Test</senderName> <headline>Nuclear Power Plant Warning</headline> <description>nuclear power plant</description> <instruction>A warning of an event at a nuclear power plant classified such as a Site Area Emergency or General Emergency as classified by the Nuclear Regulatory Commission (NRC). A Site Area Emergency is confined to the plant site; no off-site impact is expected. Typically, a General Emergency is confined to an area less than a 10-mile radius around the plant. Authorized officials may recommend evacuation or medical treatment of exposed persons in nearby areas.</instruction> <parameter> <valueName>Hotkey</valueName> <value>21</value> </parameter> <parameter> <valueName>OrgID</valueName> <value>ff574965-FA09-8745-8b9f-9b7f3268c9d6</value> </parameter> </info> </alert>

    Was this answer helpful?


  2. SHOUMIK CHAKRAVARTY 575 Reputation points
    2026-08-09T02:52:38.8766667+00:00

    Hi @Dana Johnson - If it's letting everything through rather than throwing 400s, the likely cause is that your <content> element never matches, so validation is silently skipped.

    type="application/xml" is matched against the incoming Content-Type header. If the caller sends text/xml, or omits the header, that element doesn't fire and nothing gets validated. That would look exactly like the policy doing nothing no matter what you change inside it.

    Rakesh's previous suggestion to switch to detect and trace is the right move, but context variables don't show up in the trace on their own. You have to emit them. Add this in right after validate-content:

    
    <trace source="validate-content" severity="information">
    
      <message>@{
    
        return context.Variables.ContainsKey("validationErrors")
    
          ? JsonConvert.SerializeObject(context.Variables["validationErrors"])
    
          : "validationErrors not set - the content element did not match";
    
      }</message>
    
    </trace>
    
    

    That makes the test decisive. Either you get the errors with a line and position, or you get the "not set" message, which tells you validation never ran at all.

    The fix is <content-type-map>, which exists for this. Either map a known incoming type:

    
    <validate-content unspecified-content-type-action="prevent" max-size="1048576" size-exceeded-action="prevent" errors-variable-name="validationErrors">
    
      <content-type-map missing-content-type-value="application/xml">
    
        <type from="text/xml" to="application/xml" />
    
      </content-type-map>
    
      <content type="application/xml" validate-as="xml" schema-id="MySchema" action="prevent" />
    
    </validate-content>
    
    

    or force it regardless of what arrives:

    
    <content-type-map any-content-type-value="application/xml" />
    
    

    Two things worth knowing. <content-type-map> goes before <content>. The policy reference says to set elements in the order given in the policy statement. And unspecified-content-type-action is defined as the action for content types not specified in your API schema, so it isn't the thing catching a missing header.

    One you can rule out: schema-ref isn't supported for XML schemas. Any top-level element in the XSD can act as the payload root, so there's nothing to configure there.

    Hope that helps.

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.