I have an application written in C# that processes messages placed on an Azure Service Bus Queue. This application is a BackgroundService
running as a Windows service using the AddHostedService
method.
I am creating a credentials object using a ClientSecretCredential object:
credentials = new ClientSecretCredential(
azureCreds.TenantId,
azureCreds.ClientId,
azureCreds.ClientSecret);
This is then passed to the ServiceBusQueueClient constructor, and then a processor is created.
client = new ServiceBusClient(azureNamespace, credentials, clientOptions);
processor = client.CreateProcessor(queueName, new ServiceBusProcessorOptions());
I add handlers for the messages:
processor.ProcessMessageAsync += Processor_ProcessMessageAsync;
processor.ProcessErrorAsync += Processor_ProcessErrorAsync;
Everything works well for a couple of hours. Messages are received and processed. Then I start getting the following token timeout error:
System.UnauthorizedAccessException: Put token failed. status-code: 401, status-description: ExpiredToken: The token is expired. TrackingId:<redacted>, SystemTracker:NoSystemTracker, Timestamp:<redacted>.
For troubleshooting information, see https://aka.ms/azsdk/net/servicebus/exceptions/troubleshoot.
at Azure.Messaging.ServiceBus.Amqp.AmqpConnectionScope.CreateReceivingLinkAsync(String entityPath, String identifier, AmqpConnection connection, Uri endpoint, TimeSpan timeout, UInt32 prefetchCount, ServiceBusReceiveMode receiveMode, String sessionId, Boolean isSessionReceiver, CancellationToken cancellationToken)
I searched online but everything appears to indicate that I do not have to refresh the token manually, that the Microsoft Identity library will handle that.
Has anyone else experienced this issue? Do I have to refresh the token periodically? If so, how do I know it is expiring since the expiration information is not accessible in the Service Bus Client object?
I figured out what the issue was. Since my application was running as a Windows service it was set to "Automatic" startup. But the server it was running on would boot in UTC time, then the Windows time service would change it to EST a minute or so later. Unfortunately, my service had already started so the token expiration would get confused. By changing my Windows service to start as "Automatic (Delayed Start)" it gave the time service enough time to update the system time, and everything worked properly afterwards.