Almanac

Consultant KB for Microsoft Power Automate end to end: cloud flows, desktop flows and RPA, connectors and integration, AI and agent flows, process and task mining, approvals and human-in-the-loop, ALM and solutions, governance and security, licensing and capacity, monitoring and troubleshooting, plus cross-cutting decision guides. Implementation notes, configuration decisions and the gotchas that bite on real projects. Populated by the daily author agent from the Power Automate release plans, docs repo and product blog, plus the author's own consultant notes.

feature-error-handling-and-retry-policies.mdv1 · history
CurrentApplies to Cloud flowsUpdated last monthSource Microsoft Learn

What it does

Error handling in cloud flows is built from two things: Run After settings, which decide whether an action starts after its predecessor failed, timed out or was skipped, and retry policies, which decide how many times the platform silently reattempts a transient failure before declaring it failed. Scopes wrapped in Run After conditions give you the try/catch/finally shape.

Key facts

  • The default retry policy is exponential interval. On a Low performance profile it retries twice, scaling by five minutes up to roughly a ten minute final interval. On Medium and High it retries up to 12 times, scaling by seven seconds up to roughly an hour for the last attempt.
  • You can override the policy per action with exponential interval, fixed interval, or none. Retry attempts cap at 90, maximum delay at one day, minimum delay at five seconds.
  • Every retry consumes a Power Platform request. A retrying action against a throttled endpoint burns through your allocation while achieving nothing.
  • Action Timeout sets the maximum duration across retries and asynchronous responses for that action. It does not change the timeout of a single HTTP request.
  • Outbound synchronous requests and inbound requests both time out at 120 seconds. Outbound asynchronous requests are configurable up to 30 days.
  • The workflow() function returns the run's ID, name, environment and flow display name as JSON, which is what you log from a catch scope to make failures traceable.
  • result() against a scope name returns the status, inputs, outputs and error of every action inside it, so a catch scope can report which specific action failed.
  • A flow whose trigger or actions fail continuously is switched off after 14 days.

When to use / skip

Every flow that touches a system of record needs a catch scope. Every flow that anyone depends on needs the failure to reach a human or a ticket queue, because nobody watches run history voluntarily. Where you can skip it is throwaway personal automation and flows where a failed run is genuinely harmless and self-correcting on the next trigger. Turning retries off entirely is right for non-idempotent actions — a payment, a "create record", an email — where a silent second attempt is worse than a visible failure.

Configuration decisions

  • Which actions are idempotent, and therefore which can keep the default retry policy and which need it set to none.
  • Whether a failure should stop the run, or be caught, logged and allowed to continue with a compensating path.
  • Where failures are reported — Teams, email, a Dataverse log table, a ticketing system — and who owns the queue.
  • Whether a finally scope is needed for cleanup, and how it's configured to run on all four Run After outcomes.
  • Action timeouts on long-running calls, particularly where the default retry ladder would keep a flow occupied for an hour before failing.

Gotchas

  • Retries are invisible in the run history summary. A flow that looks like it took 55 minutes was probably retrying a dead endpoint at exponential intervals, and someone paid for every attempt.
  • A catch scope only runs after the try scope. Actions that failed outside the scope aren't caught, and neither is a Terminate inside the try.
  • The finally scope needs all four Run After conditions ticked. Tick only "is successful" and "has failed" and it gets skipped when the try scope was itself skipped.
  • Default retries on a non-idempotent action produce duplicates. Duplicate approval requests and duplicate records are the classic symptoms, and the run history shows one action.
  • Secure outputs hides the error payload from run history as well as from prying eyes, which makes support considerably harder. Decide deliberately.
  • A caught and handled failure makes the run report as Succeeded. If your monitoring counts failed runs, handled errors become invisible.

Consultant notes

  • Build a reusable error-handler child flow early in the engagement — takes the run URL, flow name and error detail, writes a log row and notifies. Then every flow gets the same handling for the cost of one action.
  • Make the client decide who owns flow failures before go-live. The technical pattern is easy; the operational ownership is what actually gets missed.
  • The 14-day auto-disable rule catches people out after a system decommission. Warn them that a consistently failing flow will be switched off, not just noisy.
  • When reviewing an inherited estate, check retry policies on write actions first. Duplicate records from default retries are common and clients rarely connect the two.

Worth revisiting after any change to retry defaults, or the first time a client asks why duplicates appeared.

Was this accurate?