Using Polly to retry after HttpStatusCode.Unauthorized

I'm replying to this old question just to point out the Polly wiki page where this pattern was official documented:

retry-to-refresh-authorization

In particular this is the code snippet suggested:

var authorisationEnsuringPolicy = Policy
    .HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.Unauthorized) 
    .RetryAsync(
       retryCount: 1, // Consider how many retries. If auth lapses and you have valid credentials, one should be enough; too many tries can cause some auth systems to blacklist. 
       onRetryAsync: async (outcome, retryNumber, context) => FooRefreshAuthorizationAsync(context), 
      /* more configuration */); 

var response = authorisationEnsuringPolicy.ExecuteAsync(context => DoSomethingThatRequiresAuthorization(context), cancellationToken);

The FooRefreshAuthorizationAsync(...) method can obtain a new authorization token and pass it to the delegate executed through the policy using Polly.Context.


I might be late to the game but I leave here a post for future readers. I have created two slightly different solutions for this refresh token with retry problem.

Retry policy, Delegating Handler and Custom exception

  • Here is sequence diagram which depicts the communication flow
  • Here is the full source code

refresh token in case of 401

Retry policy, Delegating Handler and Polly.Context

This version separates the responsibilities in a different way:

  • Here is sequence diagram which depicts the communication flow
  • Here is the full source code

refreshing token


To use ExecuteAsync() you must declare the policy as .RetryAsync(...), not .Retry(...).

If your actual code reads exactly as the code sample above, the .ExecuteAsync(...) will be throwing for the mismatch between .Retry(...) [a sync policy] and .ExecuteAsync(...) [an async execution]. Since this exception is thrown, CallApiAsync() is indeed never invoked. You should be able to see the thrown exception, when calling MakeGetRequestAsync()

Overall code approach looks good tho: this retry-refreshing-authentication is a proven pattern with Polly!