Power Automate and Power Platform Support Services for the Netherlands
Managed support, project rescue, and proactive monitoring for Dutch businesses running Power Automate, Power Apps, and Dynamics 365 Customer Engagement, inside CET business hours.
Need reliable Power Automate and Power Platform support in the Netherlands? Solzet provides managed services, project rescue, and proactive monitoring for Dutch businesses. Our engineers work from Yerevan inside CET business hours, with a working day that starts before yours, and cover complex flow troubleshooting, connector licensing, and Power Platform governance. We support cloud flows, desktop flows, Power Apps, Power Pages, Dataverse, and Dynamics 365 Customer Engagement. We help Dutch companies stabilize the automation they already run, prevent the outages that come from expired connections and unowned flows, and get more out of the Microsoft 365 and Power Platform investment they are already paying for.
What does Power Platform support for the Netherlands cover?
What we support. Power Automate cloud flows and desktop flows, Power Apps, Power Pages, Dataverse, custom PCF controls, and Dynamics 365 Customer Engagement. Not Business Central, not Finance and Operations.
How it is delivered. Remotely from Yerevan, in your own Microsoft tenant, on a euro denominated B2B contract with a mutual NDA and a GDPR compliant data processing agreement.
When we are available. Armenia is UTC+4 with no daylight saving, so we are two to three hours ahead of the Netherlands and our day starts before yours.
What we are not. A Dutch company, a Dutch language helpdesk, or a manned twenty four hour operations centre. The page below is explicit about all three.
What does CET coverage actually mean when the team sits in Yerevan?
Most nearshore and offshore support claims about time zones are unverifiable. This one is arithmetic. Armenia sits on UTC+4 and has not observed daylight saving since 2012, so the gap to the Netherlands is three hours in your winter and two in your summer. Our working day therefore opens before yours does.
Period
Offset
Our 09:00 to 18:00 in your time
Overlap with a 09:00 to 17:30 Dutch day
Dutch winter time (CET, UTC+1)
Yerevan is 3 hours ahead
06:00 to 15:00 in Amsterdam
09:00 to 15:00, six hours of live overlap
Dutch summer time (CEST, UTC+2)
Yerevan is 2 hours ahead
07:00 to 16:00 in Amsterdam
09:00 to 16:00, seven hours of live overlap
Shifted schedule by agreement
Team starts two hours later in Yerevan
08:00 to 17:00 in Amsterdam in winter
Almost the whole Dutch working day
The practical consequence is the one that matters for support: a ticket raised first thing on a Dutch Monday morning lands in a working day that is already underway. It does not sit in a queue waiting for a time zone to wake up, which is the failure mode that makes far offshore support feel slow even when the engineers are good.
Which flow failures are we actually called in for?
Power Automate rarely breaks because the logic was wrong. It breaks because something around it moved: a person left, a policy changed, a licence lapsed, a volume grew. Start from the symptom you are seeing, then take the error string itself to the troubleshooting reference below for the diagnostic sequence and the fix.
What you see
What it usually is
What we do about it
A flow that ran for two years stopped overnight and the error mentions the connection
The connection was authenticated by a person, and that person has left, changed their password, or been caught by a new conditional access policy. The token behind the connection is theirs, not the company's.
Move production flows onto connection references owned by a dedicated service account inside solutions, and audit every connection in the environment for a human owner who no longer works there.
Microsoft emailed somebody who left to say the flow had been turned off
Flows are suspended after a long run of failures or a long period without a successful trigger, and the notification goes to the flow owner. If the owner has gone, nobody sees it until the business process breaks.
Give every production flow at least two owners, route platform notifications to a monitored shared mailbox or Teams channel, and add the ownership check to the joiners and leavers process.
Runs are queued, delayed, or failing with throttling errors under load
Service protection and request limits are being hit: too many Dataverse calls per user per period, an unbounded apply to each loop, or a nightly sync that lists every row and updates them one at a time.
Add pagination and concurrency control, batch the writes, split long flows into child flows, and move bulk work off the interactive window. Where the volume genuinely does not fit, move the heavy lifting to Azure and let the flow orchestrate.
A connector that always worked is suddenly blocked for everyone
A tenant data loss prevention policy changed, and the connector moved into a group that cannot share data with the other connectors in the same flow. The flow itself was not touched.
Review the DLP policy against what production actually uses, agree an exception route with the platform owner, and test policy changes in a non production environment before they reach the tenant.
The flow works for the person who built it and fails for everybody else
Two different things wear the same symptom: the running user lacks the Dataverse security role or record access the flow assumes, or they lack the licence the premium connector in the flow requires.
Separate the two by testing as the affected user, then fix the right one: security role and ownership on the data side, or the correct Power Automate licence on the connector side.
The flow cannot be moved to another environment, or it vanished when somebody left
It was built outside a solution, usually in the default environment, so it is a personal artefact rather than a deployable one. There is no clean export, no environment variable for the changing values, and no target environment to promote to.
Rebuild it as solution aware with environment variables and connection references, and put a development, test, and production path in place so the next change does not have to be repeated by hand.
A trigger fires far more often than the process it represents
An update trigger with no filtering columns and no trigger condition, so every touch of the row starts a run, including the ones the flow itself causes.
Set filtering columns and a trigger condition so the flow starts on the change it cares about, and check for the loop where a flow updates the row that triggers it.
A hybrid flow fails after a server patch or a password change
The on premises data gateway is offline, or the account the gateway runs under has expired credentials. The flow is fine; the bridge to the network is not.
Run the gateway under a managed service account, cluster it so a single machine is not a single point of failure, and alert on gateway health rather than waiting for the flow failure.
Desktop flows fail differently, and for reasons that have nothing to do with the list above: selectors, waits, sessions, and machine groups. Those are covered in depth in our Power Automate Desktop production reliability guide.
How do you troubleshoot common Power Automate flow errors?
The table above tells you which family a failure belongs to. This section is what to type and where to click once you are inside it. Everything below is written from the tickets that actually arrive on our support desk, in the order we work them: the error string as it appears in the raw output, what it means as opposed to what it appears to say, the diagnostic sequence, the resolution, and the change that stops it returning.
One note on format. There are no screenshots of the run history here, and that is deliberate: the maker portal changes with every release wave, an image cannot be searched for by somebody pasting an error into a search box, and it cannot be pasted into a support ticket. Instead the panes are named exactly, and the payloads are reproduced as text you can copy. Identifiers in the samples are shortened and fictional.
Read the run history properly before you change anything
Most wasted troubleshooting time comes from acting on the one line summary at the top of a failed run, which is a paraphrase rather than the error. Six steps get you to the real payload every time.
1
Open the run, not the flow
If the flow is solution aware, open it from Solutions rather than My flows, then use the run history list on the flow details page. The columns are Start, Duration, Status, and Error. Open the first run that failed rather than the newest run of any kind, because an intermittent failure hides behind the successes that followed it.
2
Expand the failed action, then ask for the raw output
The failed action carries a red icon. Expanding it gives you Inputs and Outputs in a friendly form, and that friendly form is not the error. Select Show raw outputs to get the JSON body the connector actually received, with a statusCode and an error object holding code and message. Telling a permission problem from a throttling problem takes those two fields, and neither of them appears in the one line summary at the top of the run.
3
Expand the trigger card as well
The card at the top of the run is the trigger, and its raw outputs are the record that started the run: the row id, _ownerid_value, _modifiedby_value, statuscode, and the columns the trigger was told to fetch. If a column that a later expression references is missing here, the trigger was never asked for it, and everything downstream evaluated against null rather than against your data.
4
Copy the identifiers before they expire
Run history is retained for 28 days. Copy the run identifier from the address bar of the open run, and the RequestId or ActivityId from the raw Dataverse error body. Those two are what a Microsoft support case needs, and they are exactly what nobody still has by the time somebody decides to open one.
5
Use Resubmit as a test, not as a fix
Resubmit replays the original trigger payload. If a resubmit succeeds with nothing changed, the cause was transient, which points at throttling or a dependency that was briefly unavailable. If it fails identically, the cause is deterministic, which points at permissions, data, or the flow itself. Check that the flow is safe to replay before you do this: a flow that writes and is not idempotent will do its work twice.
6
Check whether there is a run at all
The most misread case is an empty run history. It only lists runs that started. A trigger condition that evaluated false, filtering columns that excluded the change, or a trigger scope that excluded the user leaves no entry, no error, and no notification. That is a different diagnosis entirely, and it is the third group below.
Permission and access errors
The running identity is missing a privilege, so nothing of that type can be written
Raw output, failed Dataverse action, status 403
{
"statusCode": 403,
"body": {
"error": {
"code": "0x80040220",
"message": "Principal user (Id=8f4c...c21a, type=8, roleCount=4, privilegeCount=612, accessMode=0), is missing prvCreateincident privilege (Id=3d2b...9f01) on OTC=112 for entity 'incident'."
}
}
}
What it actually means. The identity behind the connection, which is rarely the person who reported the fault, does not hold the privilege named in the message. Read it literally. prvCreateincident is Create on the Case table, OTC=112 is that table's object type code, and accessMode=0 means a full user licence rather than an application user, so the flow is running as a named human account.
Diagnose it in this order
Take the Id from the start of the message and look it up in the environment user list. The flow almost never runs as the person you assume. With connection references, the identity is whoever authorized the connection, which after a solution import is often whoever did the import.
Read the verb and the table straight out of the privilege name: prv, then the verb, then the table logical name. prvAppendTo and prvAppend come as a pair and are the two most commonly missing, because writing a lookup needs both sides of it.
In the Power Platform admin centre, open Environments, then the environment, then Users, then that user, and list the assigned security roles. Compare them against the roles on the test user the flow was built with.
If the roles look identical, check the table itself. A table created since the role was last written carries no privileges in that role at all, which is why a flow that ran for a year fails on exactly one new table.
Resolve it
Grant the missing privilege through a security role. Do not give the account System Administrator to make the ticket go away: that hides the next four errors of the same kind and turns a permission bug into a data integrity bug.
Move the connection off the human account onto a dedicated service account or an application user, and give that identity one role written for automation and reviewed as a unit.
Re authorize the connection reference against the new identity inside the solution, then export and import. Editing the connection directly in production leaves the next deployment to undo it.
Stop it coming back. Keep one security role whose only job is to carry the privileges automation needs, assign it only to automation identities, and put it on the checklist for every new table. Auditing that role against what the flows actually call is part of a health check.
The privilege exists, but not on that particular record
What it actually means. People read this as the error above, because both are a 403 and both carry 0x80040220, and then they fix the wrong thing. The tell is that there is no prv in the message and there is an ObjectID. The account holds the privilege and cannot use it on that row. AccessRights names the operation refused, OwnerId is who owns the row, and objectBusinessUnitId is the business unit the row sits in.
Diagnose it in this order
Compare the business unit of CallingUser against objectBusinessUnitId. When they differ, the role almost always grants the privilege at Business Unit depth rather than Organization depth, so the flow fails only on records outside its own unit. That is precisely why it passed testing.
Check OwnerIdType. 8 is a user and 9 is a team. A row owned by a team the automation account does not belong to behaves exactly like a row in the wrong business unit.
Sign in as the automation identity and look for the row. A row that does not appear in any view is a read scope problem. A row that opens but will not save is a write depth problem. They are different privileges on the same role.
When it works in one environment and not another, compare the depth of the specific privilege rather than the name of the role. Roles carry the same names across environments and drift in depth once somebody edits one in production.
Resolve it
Raise the depth of the one privilege named in AccessRights, from User to Business Unit or to Organization, on the automation role only. Do not widen the human roles to fix an automation failure.
Where the data model genuinely requires records to stay inside their business unit, share the record with a team the automation identity belongs to instead of widening the role.
Where the automation crosses business units by design, put the automation identity in a team at the root business unit rather than moving the identity between units.
Stop it coming back. Test every flow as the identity that will run it, against a record owned by somebody in a different business unit. This single scenario is the reason flows pass user acceptance testing and fail in their first production week.
The flow will not even turn on after a handover or an import
Error shown on turning the flow on
Flow client error returned with status code "BadRequest" and details
"{"error":{"code":"ConnectionAuthorizationFailed","message":"The caller with
object id '3ab9...54d7' does not have permission for connection
'shared-commondataser-2f1c...9b40' under Api 'shared_commondataserviceforapps'."}}"
What it actually means. Nothing is wrong with Dataverse privileges here. The connection object itself belongs to somebody else, usually the maker who built the flow or the consultant who imported the solution, and you are not on its share list. The flow cannot start because it cannot use that credential, which is why there is no run in the history to look at.
Diagnose it in this order
Open the flow inside its solution and check which identity each connection reference is bound to. A reference bound to a departed employee shows an account that can no longer be selected.
In the maker portal, open Connections, filter to the environment, and read the Status column. Not connected means an expired or revoked token. This error means the opposite: the token is healthy and belongs to a different person.
Work out whether a conditional access policy or a password change ended the session rather than the account being wrong. A token revoked by a policy change fails every flow that person owns at the same minute, which is the quickest way to separate the two.
Resolve it
Create the connection as the automation identity, repoint the connection reference in the solution at it, and publish. This has to be done on the connection reference; there is nothing to rebind from the run history view.
Where the original owner has left, an administrator can reassign or remove the orphaned connection, but the connection reference still needs repointing, so do both in one change.
Turn the flow on again and confirm a run appears. A flow that turns on cleanly and still shows no runs has a trigger problem, covered below, not a connection problem.
Stop it coming back. Production flows should authenticate as a service identity that no leaver carries away with them, held in connection references inside a managed solution. Getting an estate into that state is the first thing we do on a takeover, and it is step two of the sequence further down this page.
Dataverse API and service protection limits
Service protection limits: the 429 that names a code
Raw output, failed Dataverse action, status 429
{
"statusCode": 429,
"headers": { "Retry-After": "41" },
"body": {
"error": {
"code": "0x80072322",
"message": "Number of requests exceeded the limit of 6000 over time window of 300 seconds."
}
}
}
What it actually means. Service protection limits are counted per user per web server over a rolling five minute window, and there are three of them with three different codes. 0x80072322 is the request count. 0x80072326 is combined execution time, twenty minutes inside the same window. 0x80072327 is more than 52 concurrent requests. The Retry-After header is a number of seconds and it is authoritative.
Diagnose it in this order
Read the code rather than the message. Too many small calls, calls that are individually expensive, and too many calls at once are three different problems, and the usual mistake is applying the first fix to all three.
Look at the loop counts in the failed run. An Apply to each over a List rows result with an update inside it makes one call per row, so six thousand rows is six thousand calls from a single identity.
Check how many flows share the automation identity. The limit is per user, so five flows on one service account share one budget and the flow that fails is not necessarily the flow that spent it.
Check concurrency control on the loops. Switching concurrency on to make a slow flow faster defaults to twenty parallel branches, and that is the usual route to 0x80072327.
Resolve it
Let the connector retry rather than catching the error yourself. The Dataverse connector honours Retry-After; a hand rolled retry that ignores the header makes the throttle worse and longer.
Replace row by row writes with a single batched call, or move the work into a bound action or plugin where the round trips disappear entirely.
Turn concurrency down rather than up on loops that write, and run the loop sequentially where order matters.
Split the work: a child flow per batch, bulk operations scheduled outside business hours, and pagination with a threshold you chose rather than the default.
Where the volume genuinely does not fit inside a flow, move the bulk step to Azure and leave the flow orchestrating it.
Stop it coming back. Give heavy automation its own identity so it cannot spend the interactive users' budget, and alert on 429 counts rather than on flow failure. Throttling shows up as slowness for weeks before it ever shows up as an error.
Connector rate limits: the 429 with no code at all
Raw output, failed action, status 429
{
"statusCode": 429,
"message": "Rate limit is exceeded. Try again in 27 seconds."
}
What it actually means. A different ceiling from the one above: applied by the connector against the connection, not by Dataverse against the user. Same status code, no 0x8007 code in the body, and the wait stated in plain text. It turns up when many flows share one connection, or when a flow fans out into child flows that reuse the parent connection.
Diagnose it in this order
Confirm there is no 0x8007 code in the body. If there is one, you are on the previous error and the fixes are different.
Count the flows bound to that connection reference. The ceiling belongs to the connection, so consolidating an estate onto one tidy service connection concentrates the load instead of spreading it.
Read the trigger frequency of every flow on that connection together rather than one at a time. A one minute recurrence sharing a connection with a high volume Dataverse trigger is the usual pairing.
Resolve it
Separate connections by workload: one for the high volume integration, one for interactive approvals, one for the reporting extract. With connection references that is a solution change, not a rebuild.
Reduce the number of calls first and the parallelism second. Fewer, larger calls beat more, smaller ones against every one of these ceilings.
Where the load is genuinely spiky, put a queue in front of it. Writing to a staging table and draining it on a schedule turns an unbounded spike into a predictable rate.
Stop it coming back. Decide the connection topology when the automation is designed. Retrofitting it onto an estate that grew by copying flows is most of the effort in a remediation.
The limit that raises no error: a run marked Succeeded that only did part of the work
Raw output of a List rows action in a successful run
What it actually means. The most expensive limit is the one that never fails. List rows returns the first page and hands back a nextLink for the rest. A flow that ignores the nextLink processes one page and reports success, so a nightly reconciliation quietly covers part of the data for months. This is the failure run history cannot show you, and it is why our monitoring counts what should have happened instead of reading run status.
Diagnose it in this order
Open the raw output of every List rows action in a successful run and search for @odata.nextLink. Its presence means there was more data and you did not fetch it.
Compare the item count going into the loop against the same query run in the app. A round number, exactly 5000, is the giveaway.
Open Settings on the action and read the pagination threshold. Off means one page. On with a threshold below the real row count is the same bug with a larger number.
Watch for the related cap in loops, which at least announces itself: "The number of items in the 'foreach' loop exceeds the maximum allowed limit of '100000'."
Resolve it
Turn pagination on, set the threshold above the largest result you expect, and add a check that fails the run loudly when the count comes back at exactly the threshold.
Better, do not fetch the rows at all. Filter server side so the query matches the business rule, select only the columns you use, and let Dataverse do the work. Most five thousand row extracts exist because the filtering happens in the flow.
For genuinely large sets, page deliberately with a Do until on the nextLink, or move the extract to a scheduled job outside the flow.
Stop it coming back. Every scheduled flow that moves data should finish by writing the number of rows it handled to a log table, with a reconciliation comparing that number against the source. That check turns a silent truncation into an alert on the morning it starts, rather than a discovery at year end.
Trigger failures
The flow never runs and the run history is empty
Trigger configuration, as entered in the designer
Trigger condition (Settings, Trigger Conditions)
@equals(triggerOutputs()?['body/statuscode'], 1)
Select columns (on the trigger itself)
name,ownerid,createdon
What it actually means. statuscode is not in Select columns, so triggerOutputs()?['body/statuscode'] is null on every evaluation, the condition never equals 1, and the flow never starts. There is no run, no failure, and no notification, which is why this reaches a support desk as "the flow is broken" with nothing at all to look at.
Diagnose it in this order
Confirm the flow is actually on. A flow suspended after a run of failures looks identical from an empty run history.
Read Select columns and the trigger condition side by side. Every column the condition names has to be in that list, spelled as the logical name, or it evaluates to null and the condition is false forever.
Check the leading @. A condition entered without it is treated as a literal string and never matches. Conditions in this box are written unwrapped, without the square brackets used elsewhere in the designer.
Check the trigger scope. Organization, Business Unit, Parent Child Business Unit, and User change which records fire it at all. A User scope trigger fires only on rows owned by the flow owner, and a handover changes the owner.
Check the change type against reality. A row created and then updated by the same process fires an Added trigger once, and a Modified trigger with filtering columns fires only when one of those columns changes.
Only then look at the data. Pull the record and read the columns the condition names. A good share of these tickets end with the data having never matched the condition in the first place.
Resolve it
Add every column the condition references to Select columns, republish, and change one record by hand to test.
Where the condition needs something the trigger cannot watch, invert the design: trigger broadly and filter in a first condition step, so the run exists and is visible. You pay for that in run count and get diagnosability back.
Set the trigger scope explicitly, and set it to Organization for anything that serves the business rather than one person.
Retest as a user who is not you, on a record you do not own.
Stop it coming back. A trigger condition is code with no error output and no test coverage. Keep it in source control with the solution, review it in the same change as the flow, and write down for every production trigger exactly which change is supposed to start it.
The flow triggers itself and the run count climbs all night
Trigger raw outputs, one of several hundred runs in an hour
What it actually means. The account that modified the record is the account the flow runs as. The flow wrote to the row, the write fired the trigger, and the next run wrote again. Filtering columns limit which columns fire a trigger, but they do not stop a flow triggering itself when it writes to one of the columns in that list.
Diagnose it in this order
Expand the trigger card on several consecutive runs and read the formatted value of _modifiedby_value. If it is your automation identity, the loop is self inflicted.
Compare the columns in Select columns against the columns the flow writes. Any overlap is the loop.
Look for a second flow doing the same thing. Two flows that each update a row the other watches produce the same pattern with two identities instead of one.
Check classic workflows and plugins on the same table before rewriting anything, because the loop is often between a flow and a plugin rather than inside the flow at all.
Resolve it
Add a trigger condition that excludes the automation identity, along the lines of @not(equals(triggerOutputs()?['body/_modifiedby_value'], variables('AutomationUserId'))). Hold the identifier in an environment variable rather than pasting a guid into the condition, so the same solution works in every environment.
Narrow Select columns to the columns a human changes, and keep the columns the flow writes out of that list.
Where a flow genuinely has to write to the column it watches, split it in two: one flow reacts, another writes, and neither watches the other's output.
Turn the flow off before you fix it if it is still running. A loop left going while you edit consumes the same request budget as the throttling errors above.
Stop it coming back. Exclude the automation identity from every trigger its own flows can write to, as a standard applied when the flow is built rather than a repair applied when somebody notices the run count. The environment variable holding that identity makes it a one line addition to any new flow.
The trigger fails immediately after a solution import
Raw output, first run after import, status 404
{
"statusCode": 404,
"body": {
"error": {
"message": "Resource not found for the segment 'new_projectstages'."
}
}
}
What it actually means. The flow is asking the target environment for a table or column that does not exist there. The same cause also appears when turning the flow on, worded as a dynamic operation request to the Dataverse connector failing with status code NotFound. It happens when the flow was built against an unmanaged change in development that never made it into the solution, or when a publisher prefix differs between environments so the component arrives under another name.
Diagnose it in this order
Read the segment name in the message. That is the entity set name, the plural logical name including the publisher prefix, and it names exactly which component is missing.
Look for that table or column in the solution in the target environment. A component that exists in development and is absent from the solution is the usual answer, and it is invisible in development because everything works there.
Compare publisher prefixes across environments. A component created under a different prefix imports under a different name, and the reference stored inside the flow definition does not follow it.
Check every environment variable and connection reference for an empty current value. A variable with no value in the target environment produces a request against an empty segment and fails the same way.
Compare the flow definition between environments by exporting the solution and reading the JSON, rather than by looking at the two designers side by side.
Resolve it
Add the missing component to the solution in development, export, and import again. Creating it by hand in production works until the next import quietly reverses it.
Set the current value of every environment variable as part of the import rather than afterwards, so the first run does not fail on an empty value.
Where the prefix genuinely differs, align the publisher rather than editing the flow, because otherwise every future component carries the same problem.
Stop it coming back. This whole class of error disappears once development, test, and production are joined by managed solutions and a repeatable pipeline. Where an estate cannot import cleanly at all, the honest description is a rescue rather than a support ticket.
Two things sit alongside this reference. Finding the failure in the first place, rather than reading one you already have, is how to monitor flows and set up alerts for failures, and a wider lookup of error codes with a note on which deserve an alert is the error code index in that section. If the same three errors keep returning on different flows, the fault is not in the flows. It is in ownership, licensing, environment strategy, or the absence of a deployment path, and fixing them one ticket at a time is the expensive way to find that out. A scoped, evidence backed read of the current state is what our Dynamics 365 health check and technical audit produces, and where the estate cannot be imported, deployed, or safely changed at all, the honest description is our project rescue and takeover service rather than a support ticket. If what you need is the automation built or rebuilt properly in the first place, that is our Power Automate consulting for cloud flows and desktop RPA.
How do you monitor Power Automate flows and set up alerts for failures?
Everything above assumes somebody already knows a flow failed. In most estates we take over, nobody does. Power Automate emails the flow owner when a run fails and again when it suspends the flow after a long run of failures, and in a company of any age that address belongs to somebody who has left, or to a maker who filtered those messages into a folder in the first month. The business finds out when the invoices do not go out.
Monitoring Power Automate properly is four layers, and they are worth building in this order: see the failures, be told about them, see the whole tenant, and stop the platform reporting success on work it did not do. The first two can be in place for your most important flows in an afternoon. The fourth is the one that finds the failures nobody knew they had.
This is the build guide. Reading a failure once you have it is a different job, covered in the troubleshooting reference above, and the error code index at the end of this section says which errors deserve an alert and which should be absorbed by a retry and counted instead.
Layer one
See the failures: run history, the failure filter, and the views that cover more than one flow
Run history is where every investigation starts and it is also the weakest monitoring tool on the platform, because it is per flow, it is limited to the flows you can see, and it keeps 28 days. Use it properly first, then build the layers that cover what it cannot.
1
Filter to failures across a wide date range, not to the last few runs
Open the flow from Solutions if it is solution aware, then use the filter above the run history list and set Status to Failed. Widen the date range rather than leaving it on the default. A nightly flow shows its pattern over four weeks and a monthly flow shows at most one failure, so a narrow range makes an intermittent fault look like a one off. Work the oldest failure in the list rather than the newest, because the first occurrence is the one that still has a cause attached to it.
2
Use the Monitor area for a view across flows, and know what it leaves out
The Monitor area of the Power Automate portal holds cloud flow activity and desktop flow runs, which is the closest thing to a multi flow view a maker gets. It covers the flows you own or that are shared with you. That is the exact opposite of what a support desk needs, because the flows that fail unnoticed are the ones nobody owns any more. Treat this view as a maker convenience, not as coverage.
3
Check the two states that produce no runs at all
A flow that is off and a connection that is broken both produce an empty run history rather than a failure, so neither shows up in any filter built on run status. Once a week, list the flows in the environment with their state and look for anything business critical sitting at Off, and open Connections filtered to the environment and look for a status other than Connected. These two checks catch the outages that alerting on failed runs can never catch, because there is no run.
4
Pull the failures into one list with a scheduled digest
A scheduled flow using the Power Automate Management connector can list the flows in an environment and their recent runs, write one row per failure into a Dataverse table or a SharePoint list, and post a single digest at the start of the working day. One digest that a person reads beats an alert per failure that everybody filters into a folder by the second week. The identity running that digest needs rights across the environment rather than ownership of the flows, so run it as a service account with an administrator role or as a service principal.
5
Decide what a failure means before you build any alerting on it
Not every failed run is an incident. A retried action that succeeded on the second attempt, an approval that was rejected, a validation that correctly refused bad data: these are outcomes, not outages. Tag each production flow business critical, important, or best effort, and let only the first two reach a human out of hours. Alerting that fires on everything gets muted, and a muted alert is worse than none because it is believed to be working.
Layer two
Be told: failure alerts to email and Teams using Run after and Send an email (V2)
The platform will not tell anybody useful that a flow failed. It emails the flow owner, who may have left, and it turns the flow off after a long run of failures with a second email to the same person. Alerting has to be built into the flow. The pattern below takes about twenty minutes per flow and is the single highest value thing on this page.
1
Wrap the working steps in a Scope named Try
Select the actions that do the work, group them into a Scope, and rename it Try. One failure path then covers every action inside it. Without the scope you are configuring a Run after path on each action individually, which is why alerting built action by action always ends up incomplete after the third change to the flow.
2
Add the alert action and configure Run after on it
Add the alerting actions after the scope, then open Configure run after on the first of them, from the ellipsis menu on the action or from Settings in the newer designer. Untick is successful, and tick has failed, is skipped, and has timed out. Skipped is the box people leave clear and it is the one that fires when the scope never ran at all because something ahead of it stopped. A path that only listens for has failed misses a whole class of outage.
3
Put the real error in the alert with the result() function
An alert that says the flow failed sends somebody to the run history to find out what you already knew. Inside the failure path, result('Try') returns one entry per action in the scope with its name, status, and error body, so a Filter array over it produces the failing action and the connector's own message. Property names differ slightly between trigger types, so check them once against the raw outputs of a real run before you rely on them in twenty flows.
4
Send it to a shared mailbox and to Teams, not to a person
Use Send an email (V2) from the Office 365 Outlook connector to a monitored shared mailbox, and Post message in a chat or channel from the Microsoft Teams connector into the channel the team already watches. Use both. Email survives and is searchable months later, Teams is the one that actually gets read within the hour. Note that posting into a channel requires the identity behind the Teams connection to be a member of that team, which is a common reason the alert works in test and silently fails in production.
5
Include a link straight to the failed run
Nobody triages from the body of an email. Build the run URL from the workflow() function so the alert opens the exact run rather than the flow, and include the flow name, the environment, the failing action, the error code, and the identifier of the record that triggered it. Those five fields turn a notification into a ticket somebody can act on without opening a portal first.
6
Terminate with status Failed, or your own alerting hides the failure
This is the step almost every implementation misses. Once a Run after path handles the failure, the run completes and is recorded as Succeeded. The alert goes out, and at the same time the run disappears from the Failed filter, from the digest, and from every count built on run status. End the failure path with a Terminate action set to Failed, carrying the error code and message. Then the alert and the run history tell the same story.
7
Test the alert path by making the flow fail on purpose
Add a temporary action that cannot succeed, such as a Dataverse read of a record identifier that does not exist, run the flow once, and confirm that the mail arrives in the shared mailbox, the Teams message posts, and the run shows as Failed. An alerting path that has never been seen to fire is not monitoring, it is an assumption. Retest it after any change to the connections behind it.
The failure path, as expressions you can paste into the designer
Filter array
From: @result('Try')
Where: @equals(item()?['status'], 'Failed')
Compose "Run link"
@concat(
'https://make.powerautomate.com/environments/',
workflow()?['tags']?['environmentName'],
'/flows/', workflow()?['name'],
'/runs/', workflow()?['run']?['name']
)
Body of Send an email (V2) and of the Teams message
Flow: @{workflow()?['tags']?['flowDisplayName']}
Environment: @{workflow()?['tags']?['environmentName']}
Run: @{workflow()?['run']?['name']}
Failing action: @{first(body('Filter_array'))?['name']}
Error code: @{first(body('Filter_array'))?['error']?['code']}
Error message: @{first(body('Filter_array'))?['error']?['message']}
Open the run: @{outputs('Run_link')}
Last action in the failure path
Terminate
Status: Failed
Code: @{first(body('Filter_array'))?['error']?['code']}
Message: @{first(body('Filter_array'))?['error']?['message']}
Layer three
See the whole tenant: the Center of Excellence Starter Kit for inventory, audit logs, and dashboards
Per flow alerting tells you that a flow you know about broke. It says nothing about the four hundred flows nobody has looked at, which owner has left, or which premium connector is in use without a licence. That is what the Center of Excellence Starter Kit is for. It is an open source solution published by Microsoft and supported by its community rather than by Microsoft support, and it is an inventory and governance layer, not an alerting system.
1
Install it into its own environment, never into production
Create a dedicated environment with a Dataverse database for the kit and install there. Installing into production, or worse into the default environment, mixes governance tooling with the systems it is supposed to be watching and makes both harder to move later.
2
Give it one identity, with the licences and the administrator rights it actually needs
The inventory runs as a single account. Use a dedicated service account, licensed for premium Power Automate and Power Apps use, with Power Platform administrator rights so the admin connectors return the whole tenant rather than only what that account happens to own. Underlicensing this account is the reason most stalled installations stall, and the symptom is a dashboard that shows one environment out of nine.
3
Run the core inventory first and let it finish before you judge it
Turn on the sync flows in the documented order and wait. On a large tenant the first full pass can run for many hours, and until it completes the dashboard is empty or wrong. More installations are abandoned at this point than at any other, because somebody opened the report on day one and concluded the kit does not work.
4
Point the Power BI dashboard at your own environment and give it a refresh schedule
The dashboard ships as a template that has to be pointed at your own instance before it shows anything. Publish it where the platform owner will genuinely open it, set a scheduled refresh, and agree who reads it and when. A governance dashboard nobody has a reason to open is indistinguishable from not having one.
5
Turn on audit log ingestion if you want usage rather than existence
Out of the box the kit tells you what exists. To learn what is actually used, the audit log components need an application registration with rights to the Microsoft 365 management APIs and auditing switched on in the compliance portal. That difference is the whole retirement case: an app that exists is a maintenance question, an app nobody has opened in six months is a decision.
6
Enable only the governance components you intend to act on
The kit can email makers about compliance, detect orphaned flows and apps, and archive what is unused. Each of those is useful and each of them sends messages to real colleagues. Automated governance mail from a system nobody is monitoring does more damage to the platform internally than the sprawl it is chasing, so turn on one component at a time and only where somebody owns the response.
7
Budget for keeping it current, or do not install it
The kit ships regular releases and upgrades are not always seamless. Version drift is the normal reason an installation goes stale and starts reporting numbers people no longer trust. If nobody will own the upgrade, a single weekly inventory flow that you wrote and understand, writing flow name, owner, state, last run, and connectors used into a table, is the better answer for a small estate.
Layer four
Stop the silent failures: scopes, retry policies, and a custom error log in Dataverse
The failures that cost the most are the ones that never appear as failures. A flow that swallows an error, a create that ran four times because of a retry policy, an extract that processed the first page and reported success. Monitoring cannot find these afterwards. They have to be designed out.
1
Use three scopes: Try, Catch, and Finally
Try holds the work. Catch is configured to run after Try has failed, is skipped, or has timed out, and holds the alerting, the logging, and the Terminate. Finally is configured to run after every outcome of both, and holds the things that must happen either way, such as releasing a lock, writing a completion row, or clearing a processing flag on the record. Without a Finally, a failed run leaves records stuck in a status the next run will skip.
2
Set the retry policy per action rather than accepting the default
Most connector actions retry automatically with an exponential interval. That is correct for a throttling response or a briefly unavailable service, and it is wrong for a create that is not idempotent, because a create that timed out after succeeding will be retried and you get duplicate records with no error anywhere. Set the policy to none on writes that cannot be safely repeated, or make the write idempotent with an alternate key so a retry updates rather than duplicates.
3
Set an action timeout so a hanging call fails instead of waiting
An action with no timeout can hold a run open long past the point the answer would have been useful. Set the timeout on long running external calls to a duration you chose, expressed as an ISO 8601 duration such as PT2M, so the action fails, reaches the Catch scope, and raises an alert while somebody is still at their desk.
4
Log every failure to a Dataverse table, not only to a mailbox
Create one table for flow errors and write a row from every Catch scope. Columns that earn their place: flow name, environment, run identifier, the record that triggered it, failing action, status code, error code, error message, severity, occurred on, resolved on, and a resolution note. That gives you a model driven view, a count of how often each error repeats, and a history that outlives run history. Run history is gone after 28 days; a support conversation about a recurring fault is usually about a longer period than that.
5
Keep the logging write outside the scope it is reporting on
If the write to the error table sits inside Try, a failure in the logging can be caught by the same handler that is supposed to record it, and you get an alert about the alerting. Keep the log write in Catch, run it under a service identity with rights to only that table, and give it no retry loop of its own.
6
Add a business level counter for anything that moves data
A scheduled flow that reads a set and processes it should finish by writing how many rows it handled, and a check should compare that against what the source says there was. This is the only thing that catches the truncated extract described in the pagination error above, because no status, alert, or dashboard built on run outcome will ever show it. Reconciliation is what turns monitoring from a report on the platform into a report on the business process.
7
Never add a failure path without a Terminate
The most common anti pattern we find on takeover is a flow with careful error handling and no Terminate, so every handled failure is recorded as a success. The estate then looks healthy in every report while the process behind it has not run correctly for months. If a Catch scope does not end in a Terminate with status Failed, it is not error handling, it is error hiding.
Common flow error codes, what to do about each, and which ones deserve an alert
The three families above are worked through in depth higher up the page. This is the wider lookup for somebody holding an error string right now. The last column is the part that belongs to monitoring rather than to troubleshooting: a transient error should be absorbed by the retry policy and counted, a deterministic one should raise an alert the first time it happens, and alerting on both the same way is how a team learns to ignore the channel.
Error code or message
What it usually means
First fix
Alert or absorb
401 Unauthorized
The token behind the connection is no longer valid: a password change, a revoked session, a conditional access policy, or a deprovisioned account.
Reauthorize the connection, then move it off the person and onto a service identity held in a connection reference so the next password change does not repeat it.
Deterministic. Alert on the first occurrence.
403 with 0x80040220 naming a prv privilege
The identity running the flow does not hold the named privilege at all. The privilege name contains the verb and the table.
Add the privilege to a security role written for automation identities. Do not resolve it by granting System Administrator.
Deterministic. Alert on the first occurrence.
403 with SecLib::AccessCheckEx failed
The identity holds the privilege but not on that record, which is usually privilege depth, business unit, or team ownership rather than the role itself.
Raise the depth of the single privilege named in AccessRights, or share the record with a team the automation identity belongs to.
Deterministic, and often data dependent. Alert and include the record identifier.
ConnectionAuthorizationFailed
The connection object belongs to somebody else, commonly the maker who built the flow or whoever imported the solution.
Recreate the connection as the automation identity and repoint the connection reference inside the solution, then publish.
Deterministic, and invisible to run based alerting because the flow will not start. Catch it with the weekly connection check.
404 Resource not found for the segment
The flow is asking the environment for a table or column that is not there, typically after an import that left a component behind.
Add the missing component to the solution in development and import again rather than creating it by hand in the target environment.
Deterministic. Alert, and treat it as a deployment defect rather than a support ticket.
400 Bad Request naming a column or a choice value
The payload does not match the schema: an invalid choice value, a lookup that is not bound in the expected form, or a required column left empty.
Compare the action inputs against the table definition, bind lookups in the form the connector expects, and validate the value before writing it.
Deterministic. Alert, and add the validation upstream so bad data fails early.
InvalidTemplate, unable to process template language expressions
An expression evaluated against null or against the wrong type. The usual cause is a column the expression references that was never selected on the trigger.
Add the column to the trigger, and wrap optional values in coalesce so a missing value produces a default rather than a failed run.
Deterministic. Alert, and expect it on the first run after a change to the flow.
ActionFailed, no dependent actions succeeded
A scope is reporting the failure of an action inside it. The message names the scope, not the cause.
Open the scope in the run and find the action with the red icon, then read its raw output. This code is a pointer, never a diagnosis.
Depends on what is inside. Put the failing action name in the alert, not this code.
429 with 0x80072322, 0x80072326, or 0x80072327
A Dataverse service protection limit: too many requests, too much combined execution time, or too many concurrent requests, counted per identity over a rolling five minute window.
Let the connector honour the Retry-After header, then remove the cause: batch the writes, page deliberately, lower concurrency on loops that write, and give heavy automation its own identity.
Transient in the moment and structural underneath. Do not alert per occurrence. Alert on the count per day crossing a threshold.
429 with no code and a plain text wait
A connector rate limit applied against the connection rather than a Dataverse limit against the user. Many flows are sharing one connection.
Split connections by workload so the integration, the interactive approvals, and the reporting extract do not share one ceiling.
Transient. Count it, alert on frequency, and review the connection topology.
500 with 0x80040265, unexpected exception from plug-in
A plugin or custom workflow activity registered on the Dataverse operation threw an exception inside the transaction. The flow is the messenger.
Read the plugin trace log for the correlated request and fix the plugin. Changing the flow will not help and usually hides the fault.
Deterministic. Alert, and route it to whoever owns the server side code.
502 or 503 Service Unavailable
The service behind the connector was briefly unavailable. This is the case the default retry policy exists for.
Leave the retry policy in place and check the service health dashboard before investigating the flow.
Transient. Alert only if it survives the retries, and count it so a sustained outage is visible.
Timeout, or the operation has timed out
A downstream call took longer than the synchronous window allows, common on custom connectors and long running requests.
Move the call to an asynchronous pattern, split the work, or reduce what the call is being asked to do in one request.
Sometimes transient. Retry once, then alert if it repeats within the same day.
Request entity too large, or a content size limit
The payload exceeded a connector or message size limit, usually a file held in a variable or a very large query result carried between actions.
Chunk the file, pass references rather than content, and filter the query on the server rather than in the flow.
Deterministic, and volume dependent. Alert, because it will only get worse as data grows.
Status Succeeded, exactly the page size returned
Not an error at all. A list action returned one page and the flow ignored the continuation link, so part of the work was silently skipped.
Turn pagination on with a deliberate threshold, filter server side, and fail the run loudly when the count returns at exactly the threshold.
Invisible to every alert built on run status. Only a business level reconciliation counter finds it.
Building this yourself is entirely reasonable, and the steps above are the whole method rather than a teaser for a call. Where we get asked to do it instead, it comes in one of three shapes. Building or rebuilding the automation with this error handling in it from the start is our Power Automate consulting for cloud flows and desktop RPA. Finding out what is actually running first, including the orphaned flows, the unlicensed premium connectors, and a properly deployed Center of Excellence Starter Kit, is the Dynamics 365 health check and technical audit. And having somebody else own the alerting, read it every morning, and act on it before you notice is the managed support models below, where the monitoring only tier is exactly this build plus a named engineer watching what it produces.
How do you stop a business critical Power Automate flow from failing silently?
You can make a flow tell you when it fails without premium connectors and without writing code. Add a failure branch with Configure run after, set to has failed, is skipped and has timed out, inside a try and catch structure built from Scope actions. Record every failure in one shared incident list in SharePoint, with the flow, the run link, the affected records and an owner. Run a scheduled canary flow that proves the schedule itself is still running, because a flow that is off never fails. And alert on more than failure: a run that succeeded but processed zero records is exactly how billing quietly goes missing, and no run status will ever show it.
This applies wherever your flows run, not only in the Netherlands. It is the short version for one business critical flow, such as billing, invoicing or payments; the full four layer build is how to monitor flows and set up alerts for failures above.
1
Add a failure branch with Configure run after
Group the working actions in a Scope, add a notification action after it, and in Configure run after tick has failed, is skipped and has timed out instead of is successful. That branch now runs only when something went wrong. It needs no code and no premium connector: Send an email (V2) from Office 365 Outlook and Post message in a chat or channel from Microsoft Teams are standard connectors. The detailed click path, including putting the real error in the message with result() and a direct link to the run built with workflow(), is in layer two of the monitoring guide above.
2
Structure the flow as try, catch and finally scopes
Try holds the work, Catch runs after Try has failed, is skipped or has timed out and holds the alert and the logging, and Finally runs whatever the outcome to write the completion record. End Catch with a Terminate action set to Failed, so a handled failure still shows as a failed run rather than a success.
3
Record every failure in one shared incident list
Create one SharePoint list for all business critical flows, with columns for flow name, run link, the record or batch affected, the failing action, the error message, severity, owner, status and resolution note. Every Catch scope adds an item with Create item from the SharePoint connector, which is a standard connector. The list becomes the team queue: an alert says something failed, the list says who is dealing with it and what was done. A Dataverse table gives stronger security and reporting, but the Dataverse connector requires premium licensing in most cases, so check your licences before choosing it.
4
Run a canary flow that proves the schedules are still running
A scheduled flow that is turned off, suspended after repeated failures, or left with a broken connection produces no run at all, so no failure branch ever fires. Have each business critical scheduled flow write its last successful run time into a small SharePoint list, and add a separate canary flow on its own schedule that checks every row and alerts when one is older than its expected interval. Give the canary a different owner and connection from the flows it watches, and have it post a short daily all clear, so its own silence is noticed by a person.
5
Alert when a run succeeds but processes zero records
This is how billing quietly goes missing: the flow ran, every action succeeded, and the query returned nothing because a filter, a view, a date or a permission changed. After the step that fetches the work, add a Condition on the count, for example length(body('Get_items')?['value']) is equal to 0, and send an alert on a day when zero is not a normal answer. Go one step further for anything that bills or pays: write the number processed to the run log and compare it with what the source says there should have been.
6
Add a tenant wide check for failed runs
Per flow alerts only cover flows somebody remembered to build them into. A scheduled flow using the Power Automate Management connector, running under an account with administrator rights over the environment, can list the flows and their recent runs and write failures from any flow into the same incident list. The Power Automate analytics in the Power Platform admin center show run and error trends by environment as well, although they are not real time, so treat them as a weekly review rather than an alert.
What reconciliation controls stop a finance automation failing silently?
Failure alerts catch runs that break. Finance automations also need controls for runs that complete and still get the business result wrong: fewer invoices than billable items, a payment run that never happened, or the same invoice created twice after a retry. These checks compare the automation with the business, not with the platform, and they belong to the finance team as much as to whoever built the flow.
Control
What it checks
How to build it
Expected against processed count
The number of billable items, approved invoices or orders the source holds for the period, against the number the flow actually processed.
The flow writes both counts to a run log list at the end of each run; a difference raises an item in the incident list.
Value totals
The sum of amounts in the source against the sum of amounts created or posted.
Compare totals alongside the counts. A matching count with a different total points at a mapping or rounding fault, not a missing record.
Payment run check
That the payment run happened, that its line count and total match the approved invoices due, and that it was acknowledged by the receiving system before the cut off time.
A scheduled check shortly before the cut off that alerts if no payment run record, file or acknowledgement exists yet. Alerting on something that did not happen is the point.
No duplicates
That no invoice or payment reference was created twice after a retry or a manual re run.
Enforce unique values on the reference column in the list or table the flow writes to, and check for repeated references in the daily reconciliation.
Owned exceptions
That every mismatch has a named owner and a resolution before the period closes.
Mismatches stay open in the incident list until resolved, and the open items are reviewed as part of the period end checklist.
If a silent failure has already cost you an invoice run or a client, the useful first step is finding every other flow with the same weakness before it happens again. That review of flows, ownership, error handling and connections is part of our Dynamics 365 health check and technical audit, and rebuilding the billing or payment automation with these controls designed in is our Power Automate consulting for cloud flows and desktop RPA.
How does connector licensing quietly decide your bill?
Dutch mid market companies almost always come to the Power Platform from Microsoft 365, which is what makes licensing so easy to get wrong. The first flows are free, so nobody asks the question until the estate is already load bearing.
Standard connectors come with Microsoft 365, premium ones do not
The Power Automate use rights seeded into a Microsoft 365 subscription cover standard connectors: Outlook, SharePoint, Teams, OneDrive, Forms, Excel, Approvals. The moment a flow touches a premium connector, a custom connector, or the on premises data gateway, the flow needs a separate licence. This is the single most common reason a proof of concept works and the rollout does not.
Dataverse is premium, and that surprises people
Anything talking to Dataverse, and therefore anything talking to Dynamics 365 Customer Engagement, is on the premium side of the line. If your automation strategy is built on Dataverse as the data layer, which is usually the right architecture, then premium licensing is part of the design decision and not an afterthought discovered at renewal.
Per user or per flow, and the answer is not always per user
Licensing a premium flow can be attached to the people who use it or to the process itself. One tenant wide automation that every employee triggers indirectly is usually cheaper licensed per process; a team of makers each building their own premium flows is usually cheaper licensed per user. Getting this wrong in either direction is expensive, and it is one of the first things we check when we take over an estate.
RPA and AI Builder are separately licensed again
Attended desktop flows, unattended desktop flows, and AI Builder capacity are all licensed separately from cloud flows, and unattended RPA in particular carries its own requirement. A desktop automation costed as if it were a cloud flow will not survive its first budget review.
Trials expire, and they take production with them
A large share of the emergency calls we take start with a flow built by somebody on a trial licence, or by a consultant whose account has since been deprovisioned. When the licence goes, the flow stops. Part of taking over an estate is finding every flow whose continued existence depends on a licence nobody is deliberately paying for.
Check the current Microsoft licensing guide before you commit
Microsoft renames plans and changes what they include with some regularity, and the seeded rights in Microsoft 365 have been adjusted more than once. We work from the current Power Platform licensing guide for any number that goes into a budget, and we recommend you read it alongside us rather than trusting a page like this one, or any consultancy, for the figure.
We are not a licence reseller and we do not earn anything from what you buy, so the advice runs in whichever direction the numbers point, including downwards. If you are heading into a Microsoft renewal, our guide to Dynamics 365 licensing costs and renewal negotiation covers the commercial side in detail.
What does proactive monitoring mean here?
Proactive is an easy word to put on a support page. These are the four things it maps to in our engagements, and the third one is the one that actually prevents outages. The mechanics of building the first two, in your own tenant and without us, are set out step by step in how to monitor flows and set up failure alerts above.
Alerting inside your own tenant
Failure alerting is built where the flows run, not in a system you cannot see. A monitoring flow watches the runs that matter and raises a Teams message or an email to a shared, monitored destination, so an alert never depends on one person still working at the company.
Business level reconciliation, not just run history
A flow can report success and still not have done the work. For the processes where that matters, we add a check that counts what should have happened against what did, because the run history only tells you the actions completed.
A scheduled review by a named engineer
Alerts catch the outage. The review catches the drift: the flow that has been retrying every night for a month, the connection about to expire, the environment filling up, the licence about to be reassigned. That review happens on a fixed cadence and produces a short written list, not a dashboard nobody opens.
Release wave checks before they reach you
Microsoft ships two release waves a year plus continuous updates. We track what is changing in the areas your automation depends on and test the ones that touch you in a non production environment, so a platform update is a scheduled task rather than an incident.
How is managed support structured?
Support scales with how much the business depends on the platform. Most Dutch clients start in the middle row and move in one direction or the other after the first quarter.
Model
What it covers
Who it suits
Monitoring only
We put failure alerting and a health dashboard in place in your tenant, watch for failures, and tell your team what broke and why. Your people do the fixing.
Organizations with an internal maker or admin who can act, but no way of knowing something failed until a user complains.
Dedicated allocation, typically 20 to 40 hours a month
A named senior engineer with context on your environments. Flow maintenance, break fix, small enhancements as processes change, licensing reviews, and release wave checks.
The common case for a Dutch mid market company running a meaningful amount of Power Platform without a dedicated platform team.
Full managed service
A team that owns the platform with you: support plus governance, ALM, a backlog of improvements, and delivery of new automations alongside the support work.
Organizations where the Power Platform now carries processes the business cannot run without, and where new demand keeps arriving.
Response targets
Agreed in the support contract against your own severity definitions, in writing, before the engagement starts. We do not publish a single number here because it is a commercial term, not a property of the platform.
Every tier. What we will commit to is that a ticket raised at the start of a Dutch working day lands inside our working day, not the next one.
How do we move an existing estate into support?
Whether the trigger is a partner who has stopped answering, an employee who built everything and then left, or a platform that simply grew past what one person can hold, the sequence is the same.
1
Inventory what you are actually running
Before anything is fixed, we build the list nobody has: every environment, every solution, every flow and app, who owns each one, which connections they depend on, which of those connections belong to a person who has left, and which premium connectors are in use. In most estates this stage alone finds flows nobody knew were running and flows everybody assumed were.
2
Take the platform off individual people
Production automation should not depend on one employee's account. We move production flows into solutions with connection references, re point them at a dedicated service account, add a second owner to everything that matters, and route Microsoft platform notifications to a shared destination that is actually monitored.
3
Triage the broken and the fragile by business impact
The backlog gets ordered by what it costs you when it fails, not by how old the ticket is. Anything that touches invoicing, customer commitments, or a regulatory deadline goes first. Everything else is scheduled, and the things that are broken but harmless are written down rather than silently carried.
4
Put monitoring and alerting in place
We build failure alerting into your tenant, add reconciliation checks for the processes where a successful run does not prove the work was done, and set the review cadence. From this point onwards you find out about a failure from us rather than from the person waiting on the output.
5
Fix the licensing and the DLP policy against reality
We map what is in use against what is licensed and what the tenant DLP policy allows, then reconcile the three. That produces two lists: the automations that are running on borrowed time, and the licence spend that is not buying anything. Both are usually a surprise.
6
Write the runbooks
Each supported process gets a short document: what it does, what it depends on, how it fails, and what to do about each failure. This is what makes support transferable between engineers and what stops the knowledge leaving again when a person does.
7
Set the guardrails so the estate stops sprawling
Environment strategy, a DLP policy that separates business from non business connectors, a development to test to production path with managed solutions and source control, and a clear answer to who may build what and where. Governance here means citizen development stays possible and stays safe, not that it gets banned.
8
Run steady state with a monthly review
Day to day support runs against the agreed response targets, and once a month we sit down with your platform owner: what broke, what changed, what Microsoft is about to change, what the licence position looks like, and what is worth building next. The support relationship should reduce the number of incidents over time, and the review is where you check that it is.
Where the problem is bigger than the automation, for instance a Dynamics 365 rollout that has stalled or a partner who has walked away mid programme, the same discipline runs at project scale in our Dynamics 365 project rescue and takeover service, and a scoped read of the current state is available as a health check and technical audit.
How does working with a Dutch business from Armenia work?
Solzet is a CRM consultancy headquartered in Yerevan, Armenia, working on Microsoft Dynamics 365 Customer Engagement, the Power Platform, and custom-built CRM for organizations that want CRM without Microsoft licensing. We are not a Dutch company and we do not pretend to be one. What Dutch clients get instead is a senior team, English as the working language with Russian and Armenian also available, and rates that a consultancy of equivalent seniority in the Randstad does not reach. Our engineers hold Microsoft certifications across the Power Platform (PL-200, PL-400, PL-600) and Dynamics 365 (MB-210, MB-230, MB-240).
Commercially, engagements run on a B2B contract, either time and materials or fixed price per milestone, invoiced in euros with international wire transfer, and in pounds or dollars where a group prefers it. For a Dutch VAT registered business buying services from a supplier outside the EU, the reverse charge normally applies, so we invoice without VAT and you account for it in your own return. Confirm that with your own adviser, since it depends on your registration and how the services are classified.
On data, we work inside your tenant rather than moving your data to ours. Your Dataverse and Power Platform data stays in the region you already chose for your environments, and support does not copy production data to Armenia. Access is through accounts you create in your own tenant with least privilege roles, which you grant and can revoke at any time, and where a problem has to be reproduced outside production we use masked or synthetic data. Every engagement carries a mutual NDA and a GDPR compliant data processing agreement, the AVG in Dutch terms, with IP ownership defined in the statement of work.
We also work as a white label subcontractor for Microsoft partners, including partners in the Netherlands, where our consultants operate under your brand, use your tooling, and do not appear to your end client as a third party. That is a different commercial shape from the support described on this page, and both can run at once.
When are we the wrong answer?
A support page that only lists strengths is not much use to somebody trying to choose, so here are the cases where you should call somebody else. If you need end user support in Dutch, for people who will phone rather than raise a ticket, we cannot provide it. If you need engineers physically on site, in a workshop room with your operations team, a local partner will serve you better. If your automation has to be watched through the night, our standard model does not cover it and the honest answer is that a follow the sun arrangement costs what it costs.
And if your problem lives in Business Central, Dynamics 365 Finance, or Supply Chain Management, that is outside what we do at all. On the Microsoft side we work in the Customer Engagement apps of Dynamics 365 and the Power Platform, and we would rather integrate cleanly with your ERP partner than claim ground we do not hold. Where we are the right answer is the middle of the market: a Dutch company that has built real dependence on Power Automate and Power Apps, has nobody senior enough to own it full time, and needs that ownership at a price that makes sense against the size of the estate.
What do Dutch businesses ask about Power Platform support?
Do you provide Power Automate support services in the Netherlands?
Yes. We provide Power Automate and Power Platform support to Dutch businesses as a managed service, delivered remotely from Yerevan, Armenia. That covers break fix on cloud and desktop flows, proactive monitoring and alerting, connector and licensing reviews, DLP and environment governance, ALM, and new automation work alongside the support. Engagements run on a B2B contract in euros with a mutual NDA and a GDPR compliant data processing agreement. We work in your tenant, using access you grant and can revoke.
You are in Armenia, so how does support inside CET business hours work?
Armenia sits on UTC+4 all year, with no daylight saving. That makes us three hours ahead of Dutch winter time and two hours ahead of Dutch summer time, so our working day starts before yours and ends in your mid afternoon. On a standard schedule that is six hours of live overlap in winter and seven in summer, and we shift the team start time later where afternoon cover matters more. In practice it means a ticket raised at nine in the morning in Amsterdam is picked up inside a working day rather than waiting for one to open.
Are you a local Dutch supplier?
No, and we would rather say so on the page than have you find out on the call. Solzet is an Armenian company with no office in the Netherlands and no Dutch language helpdesk. What we offer instead is CET working hours, English as the working language, euro invoicing, a GDPR compliant contract, and senior Microsoft certified engineers at a rate a Dutch consultancy of the same seniority does not reach. If your requirement is on site presence in Utrecht or end user support in Dutch, a local partner is the right answer and we will say so.
Can you take over Power Platform work built by a partner or an employee who has gone?
Yes. This is a large part of what we do. Taking over an estate starts with an inventory of environments, solutions, flows, owners, and connections, because the usual reason a handover was never clean is that nobody had that list. We then move production off personal accounts and onto service accounts and connection references, triage what is broken by business impact, and document each supported process in a runbook. We do the same for stalled or abandoned Dynamics 365 Customer Engagement projects through our project rescue and takeover service.
Which Power Automate licences do our flows actually need?
It depends on the connectors. Standard connectors such as Outlook, SharePoint, Teams, and Approvals are covered by the Power Automate use rights seeded into Microsoft 365. Premium connectors, custom connectors, and the on premises data gateway require a separate licence, either attached to the users or to the process, and anything touching Dataverse or Dynamics 365 is on the premium side. Desktop flows and AI Builder are licensed separately again, with unattended RPA carrying its own requirement. Because Microsoft renames plans and adjusts what they include, we work from the current Power Platform licensing guide for anything that goes into a budget rather than from memory.
What does proactive monitoring mean in practice?
It means alerting built inside your own tenant on the flows that matter, reconciliation checks for the processes where a successful run does not prove the work was done, a named engineer reviewing the estate on a fixed cadence, and release wave changes tested before they reach your production environment. It does not mean a manned twenty four hour operations centre, and we do not describe it as one. If your automation genuinely needs cover through the night, that is a separate conversation about scope and cost, not a checkbox.
How do we get alerted when a Power Automate flow fails?
Build the alert into the flow, because the platform only emails the flow owner and that address is often a person who has left. Group the working actions into a Scope named Try, add the alerting actions after it, and open Configure run after on the first of them: untick is successful, and tick has failed, is skipped, and has timed out. Inside that path, result('Try') returns each action in the scope with its status and error body, so a Filter array over it gives you the failing action name and the connector's own message. Send that to a monitored shared mailbox with Send an email (V2) and to a Teams channel with Post message in a chat or channel, and include a link built from the workflow() function that opens the failed run directly. The step that is almost always missed is the last one: end the path with a Terminate action set to Failed, otherwise the run is recorded as Succeeded and your own alerting removes the failure from run history and from every report built on it.
How long does Power Automate keep run history, and how do we keep failures for longer?
Run history is retained for 28 days, which is shorter than most support conversations about a recurring fault. If you need a longer record, write it yourself: every Catch scope should insert a row into a Dataverse error log table holding the flow name, environment, run identifier, the record that triggered the run, the failing action, the status and error codes, the error message, a severity, and when it was resolved. That table gives you a model driven view, a count of how often each error repeats, and evidence that survives past the retention window. It also gives you something run history cannot: a place to record what was done about each failure.
A Power Automate flow failed silently and billing was not invoiced. How do we get alerted next time?
Put three things around the billing flow. A failure branch using Configure run after, set to has failed, is skipped and has timed out, that emails a shared mailbox and posts to Teams and records the failure in a shared incident list. A canary flow that alerts when the billing flow has not completed successfully within its expected interval, which catches a flow that was turned off or stopped triggering. And a check that alerts when a run succeeds but processes zero records, or fewer than the source says it should have, because that is the silent failure a run status never shows.
Can we set up Power Automate failure alerts without premium connectors or code?
Yes. Scopes, Configure run after, conditions and Terminate are built in, and Office 365 Outlook, Microsoft Teams and SharePoint are standard connectors, so a failure branch, a SharePoint incident list and a canary flow can all be built without premium licensing and without writing code beyond a few expressions such as result() and length(). Logging to a Dataverse table instead of a SharePoint list requires premium licensing in most cases, so check your licences before choosing it.
What reconciliation controls should a finance automation have?
At minimum: a comparison of the count the source expected against the count the flow processed, a comparison of value totals, a check that the payment run happened and was acknowledged before its cut off, a uniqueness rule so a retry cannot create a duplicate invoice or payment, and a named owner for every mismatch until it is resolved before the period closes. These controls catch the failures where every run reports success.
Is the Center of Excellence Starter Kit enough to monitor our flows?
No, and it is not meant to be. The CoE Starter Kit is an inventory and governance layer: it tells you which flows and apps exist, who owns them, which are orphaned, which connectors are in use, and with audit log ingestion enabled, which are actually used. It will not tell you at nine in the morning that last night's invoice run failed. That needs per flow alerting built into the flows themselves. The two are complementary, and the order we build them in is alerting first on the flows the business cannot run without, then the kit for the estate wide view. Two other things worth knowing before you install it: it is open source and supported by its community rather than by Microsoft support, and it needs a dedicated environment plus a properly licensed service account with Power Platform administrator rights, which is where most stalled installations stalled.
Where does our data sit, and how is GDPR handled?
We work inside your Microsoft tenant, so your Dataverse and Power Platform data stays in the region you already chose for your environments and is not copied to Armenia as part of support. Access is through accounts you create in your own tenant with least privilege roles, which you can revoke at any time. Where we need to reproduce a problem outside production we use masked or synthetic data. Every engagement runs under a mutual NDA and a GDPR compliant data processing agreement, which Dutch readers will know as the AVG, with IP ownership defined in the statement of work.
How is a contract with an Armenian supplier handled for VAT and payment?
We invoice in euros on a B2B contract and support international wire transfer, and we can also invoice in pounds or dollars where a group prefers it. For a Dutch VAT registered business buying services from a supplier outside the EU, the reverse charge normally applies, so we invoice without VAT and you account for it in your own return. Confirm the treatment with your own adviser, since it depends on your registration and how the services are classified.
Do you support Business Central or Dynamics 365 Finance and Operations?
No. Solzet works on the Customer Engagement side of Dynamics 365, meaning Sales, Customer Service, Field Service, and Customer Insights, plus the Power Platform: Power Apps, Power Automate, Power Pages, Dataverse, Copilot Studio, and PCF controls. We do not work with Business Central, Finance, or Supply Chain Management. If your automation needs to integrate with one of those, we build and support the integration from the Power Platform side and work with whoever owns the ERP.
How quickly can support start, and what is the minimum commitment?
A senior engineer can usually start within weeks rather than the months an internal hire takes, and an emergency stabilization can start sooner where something in production is down. For an ongoing allocation we recommend at least 20 hours a month, because below that the context retention costs more than the hours buy. Monitoring only engagements are smaller. We also take fixed price work for a defined piece of remediation where you want cost certainty before committing to a retainer.
Our flow fails with a 403 and error code 0x80040220. What do we check first?
Read the raw output rather than the summary, because two different problems share that status and that code. If the message names a privilege, such as missing prvCreateincident, the identity behind the connection does not hold that privilege at all and the fix is a security role change. If the message says SecLib::AccessCheckEx failed and carries an ObjectID, OwnerId, and AccessRights, the identity holds the privilege but not on that record, and the fix is privilege depth, record ownership, or team membership. The other thing to check immediately is which identity is actually running: with connection references it is whoever authorized the connection, which after a solution import is often the person who did the import rather than the person who built the flow.
What does "Number of requests exceeded the limit of 6000 over time window of 300 seconds" mean?
It is a Dataverse service protection limit, counted per user across a rolling five minute window, and the response carries a Retry-After header in seconds that the connector will honour on its own. There are three of these limits with three codes: 0x80072322 for the request count, 0x80072326 for combined execution time, and 0x80072327 for more than 52 concurrent requests, and each one needs a different fix. The usual cause is a loop that reads a large result set and writes one row at a time, so the answer is batching, pagination with a deliberate threshold, lower concurrency on loops that write, and moving bulk work off the interactive window. Because the limit is per user, several flows sharing one service account share one budget, so the flow that fails is often not the flow that spent it.
Our Power Automate flow does not run at all and the run history is empty. Where do we start?
An empty run history is a trigger problem, not a failure, because the history only lists runs that started. Check that the flow is on, then read the trigger condition and the Select columns list together: any column the condition references has to be in that list or it evaluates to null and the condition is false on every change. Check that the condition begins with @ and is written unwrapped, check the trigger scope, since a User scope trigger only fires on rows the flow owner owns and a handover changes the owner, and check the change type against what actually happens to the record. Only after that is it worth looking at the data itself. A flow that turns on cleanly but never runs is almost never a connection or licensing problem.
We recommend the right solution - whether that's Microsoft Dynamics 365, Power Platform, or a custom-built CRM. Some businesses need the Microsoft ecosystem. Others need full control without licensing. We deliver both.
Can we provide Power Platform support for your Dutch business?
Tell us what is running, what keeps breaking, and who owns it today. We will come back with what we would inventory first, what we think it takes to stabilize, and whether we are the right people for it.