Synchronous Policy Assignment Request

I’m relatively new to running SCCM in Native Mode, and the other day I came across an issue I hadn’t seen before.  In short, the problem was that my clients would boot into Windows PE (WinPE), but would not begin their advertised task sequence.  WinPE would think there’s nothing to do, and subsequently the client would reboot.  After some investigation, I found the error “Failed to Download Policy (Code 0x8004005)” in the SMSTS.LOG file.  And this is how I fixed the issue…..

The story was, I had built an SCCM environment in Native Mode.  I had setup everything and was beginning to flesh the server out with an OSD build that my customer could then use as a framework and begin developing their SOE.  I had setup a collection for the desktop/laptop builds, I had setup my boot images and distribution points, the PXE Service Point role was installed, and I had made my basic task sequence and advertised it to the collection.  I rebooted my client laptop off the network and WinPE started to load.  It got into the PE environment and shortly after initiating the network settings, the client just rebooted with nothing to do.  I rebooted my client again, but this time when it got into WinPE, I pressed the F8 button to break out into a command window.

If you don’t know about this feature its very handy for trouble shooting OSD problems.  In your SCCM console, open the OSD node -> Boot Images -> go to the Properties of the boot image you’re using -> Windows PE tab -> Enable Command Support (testing only).

I then copied the SMSTS.LOG file off the client workstation, to look at it in Trace32 (another must have tool).

The Problem:

This is what I found in the SMSTS.LOG file.

For a larger version of the above image click here.

From the log file, I could see that the client was not able to recieve any policy from the SCCM server.  I was aware that running SCCM in Native Mode means all communications are over SSL, so this error got me thinking that perhaps the issue I was having was one of trust/authentication/communication.  Now, I hate certificates at the best of times.  Or perhaps I just don’t understand them enough.  I understand the concept, but in practice, I _hate_ dealing with CA’s – they confuse me too easily.  I was able to find some forums around the place that discussed the specific error “Failed to Download Policy [policy number] (Code 0x80004005)” but all of the fixes I tried didn’t resolve the issue I was having. 

I did eventually resolve my issue.

The Solution:

For me, in my particular instance, I found the problem was to do with client authentication back to the SCCM server whilst in WinPE.   I had to generate a user certificate for the SCCM Network Access Account and add this to the PXE Service Point.  It turns out, you cannot use a self-signed PXE certificate when you are running SCCM in Native Mode.  The option is “suppose” to be greyed out when you are in Native Mode, but on my SCCM SP1 installation it was not – which is what lead me to believe I could use it. 

So how do you create a client authentication cert for the Network Access account?  Well this is the procedure I did:

1. I logged onto a workstation as the SCCM Network Access account. 

2. As the service account, I went to the CA’s webpage and requested a “User Certificate”.  I allowed the CA to install the certificate for me when prompted.

3. On the same computer, I then opened up MMC -> Add/Remove Snap-In -> Certificates -> User Account.  I then opened up the Personal Certificate store, and exported the User Certificate I had just been issued from the CA.  It is important to note that you need to export the certificate with the private keys. It will ask you to enter a password when you do this – just give it any password you will easily remember.  Save the certificate to a location.

4. Back on the SCCM server, login as the administrator and open up the SCCM console.  Navigate to Site Settings -> Site Systems -> go to your server -> go into properties of the PXE Service Point role.

5. On the database tab, select Import Certificate, and import the certificate you exported in step 3.  You will need to enter the password you assigned when you exported the certificate.

Once I created a client authentiation certificate for the Network Access Account and imported this on the PXE Service point – my client workstations booted up and happily retrieved their task sequences, thus beginning the OSD deployment process.

If this fix doesn’t resolve your particular issue, you may have a problem with expired or blocked certificates.  If so, take a look at this post by the Management team.  It walks you through checking for blocked/expired certificates and resolving the issue:


Use the Quota policy to configure the number of request messages that an API proxy allows over a period of time, such as a minute, hour, day, week, or month. You can set the quota to be the same for all apps accessing the API proxy, or you can set the quota based on:

  • The product that contains the API proxy
  • The app requesting the API
  • The app developer
  • Many other criteria

Don't use Quota to shield against overall traffic spikes. For that, use the Spike Arrest policy. See Spike Arrest policy.

Tip: Need help deciding which rate limiting policy to use? See Comparing Quota, Spike Arrest, and Concurrent Rate Limit Policies.


These videos introduce quota management with the Quota policy:

Intro (New Edge)

Intro (Classic Edge)

Dynamic Quota

Distributed & Synchronous

Message Weight


Rolling Window


Conditional Quota

Flow Variables

Error Handling


These policy code samples illustrate how to start and end quota periods by:

More Dynamic Quota

<Quota name="CheckQuota"> <Interval ref="verifyapikey.verify-api-key.apiproduct.developer.quota.interval">1</Interval> <TimeUnit ref="verifyapikey.verify-api-key.apiproduct.developer.quota.timeunit">hour</TimeUnit> <Allow count="200" countRef="verifyapikey.verify-api-key.apiproduct.developer.quota.limit"/> </Quota>

Dynamic quotas enable you to configure a single Quota policy that enforces different Quota settings based on information passed to the Quota policy. Another term for Quota settings in this context is "Service Plan". The dynamic Quota checks the apps' "Service Plan" and then enforces those settings.

Note: If you specify both a value and a reference for an element, then reference gets the priority. If reference does not resolve at runtime, then the value is used.

For example, when you create an API product, you can optionally set the allowed quota limit, time unit, and interval. However, setting these value on the API product does not enforce their use in an API proxy. You must also add a Quota policy to the API proxy that reads these values. See Create API products for more.

In the example above, the API proxy containing the Quota policy uses a VerifyAPIKey policy, named , to validate the API key passed in a request. The Quota policy then accesses the flow variables from the VerifyAPIKey policy to read the quota values set on the API product. For more on VerifyAPIKey flow variables, see Verify API Key policy.

Another option is to set custom attributes on individual developers or apps, and then read those values in the Quota policy. For example, you want to set different quota values per developer. In this case, you set custom attributes on the developer containing the limit, time unit, and interval. You then reference these values in the Quota policy as shown below:

<Quota name="DeveloperQuota"> <Identifier ref="verifyapikey.verify-api-key.client_id"/> <Interval ref="verifyapikey.verify-api-key.developer.timeInterval"/> <TimeUnit ref="verifyapikey.verify-api-key.developer.timeUnit"/> <Allow countRef="verifyapikey.verify-api-key.developer.limit"/> </Quota>

This example also uses the VerifyAPIKey flow variables to reference the custom attributes set on the developer.

You can use any variable to set the parameters of the Quota policy. Those variables can come from:

  • Flow variables
  • Properties on the API product, app, or developer
  • A KVM or vault
  • A header, query parameter, form parameter, etc

For each API proxy, you can add a Quota policy that either references the same variable as all the other Quota policies in al the other proxies, or the Quota policy can reference variables unique for that policy and proxy.

Start Time

<Quota name="QuotaPolicy" type="calendar"> <StartTime>2017-02-18 10:30:00</StartTime> <Interval>5</Interval> <TimeUnit>hour</TimeUnit> <Allow count="99"/> </Quota>

For a Quota with set to , you must define an explicit value. The time value is the GMT time, not local time. If you do not provide a value for a policy of type , Edge issues an error.

The Quota counter for each app is refreshed based on the , , and values. For this example, the Quota begins counting at 10:30 am GMT on February 18, 2017, and refreshes every 5 hours. Therefore, the next refresh is at 3:30 pm GMT on February 18, 2017.

Access Counter

<Quota name="QuotaPolicy"> <Interval>5</Interval> <TimeUnit>hour</TimeUnit> <Allow count="99"/> </Quota>

An API proxy has access to the flow variables set by the Quota policy. You can access these flow variables in the API proxy to perform conditional processing, monitor the policy as it gets close to the quota limit, return the current quota counter to an app, or for other reasons.

Because access the flow variables for the policy is based on the policies attribute, for the policy above named you access its flow variables in the form:

  • : Allowed count.
  • : Current counter value.
  • : UTC time when the counter resets.

There are many other flow variables that you can access, as described below.

For example, you can use the following AssignMessage policy to return the values of Quota flow variables as response headers:

<AssignMessage async="false" continueOnError="false" enabled="true" name="ReturnQuotaVars"> <AssignTo createNew="false" type="response"/> <Set> <Headers> <Header name="QuotaLimit">{ratelimit.QuotaPolicy.allowed.count}</Header> <Header name="QuotaUsed">{ratelimit.QuotaPolicy.used.count}</Header> <Header name="QuotaResetUTC">{ratelimit.QuotaPolicy.expiry.time}</Header> </Headers> </Set> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> </AssignMessage>

First Request

<Quota name="MyQuota"> <Interval>1</Interval> <TimeUnit>hour</TimeUnit> <Allow count="10000"/> </Quota>

Use this sample code to enforce a quota of 10,000 calls per one hour. The policy resets the quota counter at the top of each hour. If the counter reaches the 10,000-call quota before the end of the hour, calls beyond 10,000 are rejected.

For example, if the counter starts at , then it resets to 0 at (1 hour from the start time). If the first message is received at and the message count reaches 10,000 before , calls beyond that count are rejected until the count resets at the top of the hour.

The counter reset time is based on the combination of and . For example, if you set to 12 for a of hour, then the counter resets every twelve hours. You can set to minute, hour, day, week, or month.

You can reference this policy in multiple places in your API proxy. For example, you could place it on the Proxy PreFlow so it is executed on on every request. Or, you could place it on multiple flows in the API proxy. If you use this policy in multiple places in the proxy, it maintains a single counter that is updated by all instances of the policy.

Alternatively, you can define multiple Quota policies in your API proxy. Each Quota policy maintains its own counter, based on the attribute of the policy.

Set identifier

<Quota name="QuotaPolicy" type="calendar"> <Identifier ref="request.header.clientId"/> <StartTime>2017-02-18 10:00:00</StartTime> <Interval>5</Interval> <TimeUnit>hour</TimeUnit> <Allow count="99"/> </Quota>

By default, a Quota policy defines a single counter for the API proxy, regardless of the origin of a request. Alternatively, you can use the attribute with a Quota policy to maintain separate counters based on the value of the attribute.

For example, use the tag to define separate counters for every client ID. On a request to your proxy, the client app then passes a header containing the , as shown in the example above.

You can specify any flow variable to the attribute. For example, you could specify that a query param named contains the unique identifier:

<Identifier ref=""/>

If you use the VerifyAPIKey policy to validate the API key, or the OAuthV2 policies with OAuth tokens, you can use information in the API key or token to define individual counters for the same Quota policy. For example, the following tag uses the flow variable of a VerifyAPIKey policy named :

<Identifier ref="verifyapikey.verify-api-key.client_id"></Identifier>

Each unique value now defines its own counter in the Quota policy.


<Quota name="QuotaPolicy"> <Interval>1</Interval> <TimeUnit>day</TimeUnit> <Allow> <Class ref="request.header.developer_segment"> <Allow class="platinum" count="10000"/> <Allow class="silver" count="1000" /> </Class> </Allow> </Quota>

You can set Quota limits dynamically by using a class-based Quota count. In this example, the quota limit is determined by the value of the header passed with each request. That variable can have a value of or . If the header has an invalid value, the policy returns a quota violation error.

Note: You cannot use both the and elements in the same Quota policy.

About the Quota policy

A Quota is an allotment of request messages that an API proxy can handle over a time period, such as minute, hour, day, week, or month. The policy maintains counters that tally the number of requests received by the API proxy. This capability enables API providers to enforce limits on the number of API calls made by apps over an interval of time. Using Quota policies you can, for example, limit apps to 1 request per minute, or to 10,000 requests per month.

Note: When an API proxy reaches its Quota limit, subsequent API calls are rejected; Apigee Edge returns an error message for every request that exceeds the Quota. The Quota policy provides the ability to reset Quotas on-the-fly, after an app has exceeded its limit.

For example, if a Quota is defined as 10,000 messages per month, rate-limiting begins after the 10,000th message. It doesn't matter whether 10,000 messages were counted on the first day or the last day of that period; no additional requests area allowed until the Quota counter automatically resets at the end of the specified time interval, or until the Quota is explicitly reset using Reset Quota policy.

A variation on Quota called SpikeArrest prevents traffic spikes (or bursts) that can be caused by a sudden increase in usage, buggy clients, or malicious attacks. For more information on SpikeArrest, see Spike Arrest policy.

Quotas apply to individual API proxies and are not distributed among API proxies. For example, if you have three API proxies in an API product, a single quota is not shared across all three even if all three use the same quota policy configuration.

Quota policy types

The Quota policy supports several different types of policies: default, , , and . Each type defines when the quota counter starts and when it resets, as shown in the following table:

Time UnitDefault (or null) resetcalendar resetflexi reset
minuteStart of next minuteOne minute after One minute after first request
hourTop of next hourOne hour after One hour after first request
dayMidnight GMT of the current day24 hours after 24 hours after first request
weekMidnight GMT Sunday at the end of the weekOne week after One week after first request
monthMidnight GMT of the last day of the monthOne month after One month after first request

For , you must specify the value of .

The table does not list the value for the type. Rolling window quotas work by setting the size of a quota "window", such as a one hour or one day window. When a new request comes in, the policy determines if the quota has been exceeded in the past "window" of time.

For example, you define a two hour window that allows 1000 requests. A new request comes in at 4:45 PM.The policy calculates the quota count for the past two hour window, meaning the number of requests since 2:45 PM. If the quota limit has not been exceeded in that two-hour window, then the request is allowed.

One minute later, at 4:46 PM, another request comes in. Now the policy calculates the quota count since 2:46 PM to determine if the limit has been exceeded.

For the type, the counter never resets, but is recalculated on each request.

Understanding quota counters

By default, a Quota policy maintains a single counter, regardless of how many times you reference it in an API proxy. The name of the quota counter is based on the attribute of the policy.

For example, you create a Quota policy named with a limit of 5 requests and place it on multiple flows (Flow A, B, and C) in the API proxy. Even though it is used in multiple flows, it maintains a single counter that is updated by all instances of the policy:

  • Flow A is executed -> MyQuotaPolicy is executed and its counter = 1
  • Flow B is executed -> MyQuotaPolicy is executed and its counter = 2
  • Flow A is executed -> MyQuotaPolicy is executed and its counter = 3
  • Flow C is executed -> MyQuotaPolicy is executed and its counter = 4
  • Flow A is executed -> MyQuotaPolicy is executed and its counter = 5

The next request to any of the three flows is rejected because the quota counter has reached its limit.

Using the same Quota policy in more than one place in an API proxy flow, which can unintentially cause Quota to run out faster than you expected, is an anti-pattern described in The Book of Apigee Edge Antipatterns.

Alternatively, you can define multiple Quota policies in your API proxy and use a different policy in each flow. Each Quota policy maintains its own counter, based on the attribute of the policy.

Or, use the or elements in the Quota policy to define multiple, unique counters in a single policy. By using these elements, a single policy can maintain different counters based on the app making the request, the app developer making the request, a client ID or other client identifier, and more. See the examples above for more information on using the or elements.

Note: Quota counters are scoped to the API proxy that contains the Quota policy. If multiple API proxies contain Quota policies with the same name, the counters are maintained separately.

Time notation

All Quota times are set to the Coordinated Universal Time (UTC) time zone.

Quota time notation follows the international standard date notation defined in International Standard ISO 8601.

Dates are defined as year, month, and day, in the following format: . For example, represents February 4, 2015.

Time of day is defined as hours, minutes, and seconds in the following format: . For example, represents the time one second before midnight.

Note that two notations, and , are available to distinguish the two midnights that can be associated with one date. Therefore is the same date and time as . The latter is usually the preferred notation.

Getting quota settings from the API product configuration

You can set quota limits in API product configurations. Those limits don't automatically enforce quota. Instead, you can reference product quota settings in a quota policy. Here are some advantages of setting a quota on the product for quota policies to reference:

  • Quota policies can use a uniform setting across all API proxies in the API product.
  • You can make runtime changes to the quota setting on an API product, and quota policies that reference the value automatically have updated quota values.

For more information on using quota settings from an API product, see the "Dynamic Quota" example above..

For info on configuring API products with quota limits, see Create API products.

Element reference

Following are elements and attributes you can configure on this policy. Note that some element combinations are mutually exclusive or not required. See the samples for specific usage. The variables below are available by default when a Verify API Key policy called "VerifyAPIKey" is used to check the app's API key in the request. The variable values come from the quota settings on the API product that the key is associated with, as described in Getting quota settings from the API product configuration.

<Quota async="false" continueOnError="false" enabled="true" name="Quota-3" type="calendar"> <DisplayName>Quota 3</DisplayName> <Allow count="2000" countRef="verifyapikey.VerifyAPIKey.apiproduct.developer.quota.limit"/> <Allow> <Class ref="request.queryparam.time_variable"> <Allow class="peak_time" count="5000"/> <Allow class="off_peak_time" count="1000"/> </Class> </Allow> <Interval ref="verifyapikey.VerifyAPIKey.apiproduct.developer.quota.interval">1</Interval> <TimeUnit ref="verifyapikey.VerifyAPIKey.apiproduct.developer.quota.timeunit">month</TimeUnit> <StartTime>2017-7-16 12:00:00</StartTime> <Distributed>false</Distributed> <Synchronous>false</Synchronous> <AsynchronousConfiguration> <SyncIntervalInSeconds>20</SyncIntervalInSeconds> <SyncMessageCount>5</SyncMessageCount> </AsynchronousConfiguration> <Identifier/> <MessageWeight/> </Quota>

<Quota> attributes

<Quota async="false" continueOnError="false" enabled="true" name="Quota-3" type="calendar">

The following attributes are specific to this policy.


Use to set when the quota counter starts counting usage. See the table above for more information.

If you omit a value, the counter begins when the first request message is received from an app.

Valid values include:

  • : Configure a quota based on an explicit start time. The Quota counter for each app is refreshed based on the , and values that you set.
  • : Configure a quota that uses a "rolling window" counter that advances by the time interval that you specify. The counter starts when the first message is received from the client plus the interval that you define.
  • : Configure a quota that causes the counter to begin when the first request message is received from an app, and resets based on the and values.

The following attributes are common to all policy parent elements.


The internal name of the policy. Names may contain letters, numbers, spaces, hyphens, underscores, and periods. Names cannot exceed 255 characters.

Optionally, use the element to label the policy in the management UI proxy editor with a different, natural-language name.


Set to to return an error when a policy fails. This is expected behavior for most policies.

Set to to have flow execution continue even after a policy fails.


Set to to enforce the policy.

Set to to "turn off" the policy. The policy will not be enforced even if it remains attached to a flow.


This attribute is deprecated.


<DisplayName> element

Use in addition to the


Leave a Reply

Your email address will not be published. Required fields are marked *