Trying to obtain file upload SAS URI fails with "Connection reset by peer"

Timo 20 Reputation points
2023-05-29T13:08:27.27+00:00

I'm trying to upload a file to a blob storage using the C# Azure IoT Device SDK but I am stopped in my tracks because GetFileUploadSasUriAsync throws an exception. Here is a minimal example:

using Microsoft.Azure.Devices.Client.Transport;
using Microsoft.Azure.Devices.Client;
using System.Security.Cryptography.X509Certificates;

string deviceId = "my-device";

string certPath = "my-certificate.pfx";

var cert = new X509Certificate2(certPath);

string iotHubHostName = "my-iot-hub.azure-devices.net";

var deviceAuthentication = new DeviceAuthenticationWithX509Certificate(deviceId, cert);

DeviceClient deviceClient = DeviceClient.Create(iotHubHostName, deviceAuthentication, TransportType.Mqtt);

var fileUploadSasUriRequest = new FileUploadSasUriRequest
{
	BlobName = "my-file.log"
};

FileUploadSasUriResponse sasUri = await deviceClient.GetFileUploadSasUriAsync(fileUploadSasUriRequest);

And here is the corresponding stacktrace:

Unhandled exception. Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException: An error occurred while sending the request.                                                                                      
 ---> System.Net.Http.HttpRequestException: An error occurred while sending the request.                                                                                                                                       
 ---> System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer.                                                                                                                      
 ---> System.Net.Sockets.SocketException (104): Connection reset by peer                                                                                                                                                       
   --- End of inner exception stack trace ---                                                                                                                                                                                  
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)                                                                                           
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)                                                                             
   at System.Net.Security.SslStream.<FillHandshakeBufferAsync>g__InternalFillHandshakeBufferAsync|189_0[TIOAdapter](TIOAdapter adap, ValueTask`1 task, Int32 minSize)                                                          
   at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](TIOAdapter adapter)                                                                                                                                           
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)                                                                 
   at System.Net.Security.SslStream.ReplyOnReAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Byte[] buffer)                                                                                                                
   at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](TIOAdapter adapter, Memory`1 buffer)                                                                                                                         
   at System.Net.Http.HttpConnection.InitialFillAsync(Boolean async)                                                                                                                                                           
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)                                                                                             
   --- End of inner exception stack trace ---                                                                                                                                                                                  
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)                                                                                             
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)                                          
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)                                                                                                
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, Cancel
lationToken originalCancellationToken)                                                                                                                                                                                         
   at Microsoft.Azure.Devices.Client.Transport.HttpClientHelper.ExecuteAsync(HttpMethod httpMethod, Uri requestUri, Func`3 modifyRequestMessageAsync, Func`2 isSuccessful, Func`3 processResponseMessageAsync, IDictionary`2 er
rorMappingOverrides, CancellationToken cancellationToken)                                                                                                                                                                      
   --- End of inner exception stack trace ---                                                                                                                                                                                  
   at Microsoft.Azure.Devices.Client.Transport.HttpClientHelper.ExecuteAsync(HttpMethod httpMethod, Uri requestUri, Func`3 modifyRequestMessageAsync, Func`2 isSuccessful, Func`3 processResponseMessageAsync, IDictionary`2 er
rorMappingOverrides, CancellationToken cancellationToken)                                                                                                                                                                      
   at Microsoft.Azure.Devices.Client.Transport.HttpClientHelper.PostAsync[T1,T2](Uri requestUri, T1 entity, IDictionary`2 errorMappingOverrides, IDictionary`2 customHeaders, CancellationToken cancellationToken)             
   at Microsoft.Azure.Devices.Client.Transport.HttpTransportHandler.GetFileUploadSasUriAsync(FileUploadSasUriRequest request, CancellationToken cancellationToken)                                                             
   at Program.<Main>$(String[] args) in /home/timo/.../Program.cs:line 35                                                                                                                
   at Program.<Main>(String[] args)

Using Wireshark I have observed that the server resets the connection immediately after the clients final TLS handshake message.

What could be going on here? In case it is relevant, my IoT Hub is set to authenticate with the blob storage via "key-based" authentication.

Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
2,598 questions
Azure IoT Hub
Azure IoT Hub
An Azure service that enables bidirectional communication between internet of things (IoT) devices and applications.
1,153 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. AshokPeddakotla-MSFT 30,081 Reputation points
    2023-05-30T07:45:52.63+00:00

    @Timo Welcome to Microsoft Q&A forum!

    There could be several reasons for this error, such as network issues, firewall settings, or server-side issues. Here are some steps you can take to troubleshoot the issue:

    • Ensure all pre-requisites met as per Upload files from your device to the cloud with Azure IoT Hub (.NET)
    • Make Sure port 8883 should be open in your firewall. The sample in this article uses MQTT protocol, which communicates over port 8883. This port may be blocked in some corporate and educational network environments. For more information and ways to work around this issue, see Connecting to IoT Hub (MQTT).
    • Try using a different transport protocol: you can try using HTTP or AMQP instead to see if the issue persists.

    Also, see IotHubCommunicationException Class for handling the exception.

    Do let us know if that helps or need any further help.