Skip to content

DescribeTagsAsync can take a sync path resulting in a PlatformNotSupportedException exception on .NET Android #3626

Closed
@mscottford

Description

@mscottford

Describe the bug

Calling DescribeTagsAsync on .NET 8 Android causes a PlatformNotSupportedException, because the synchronous HttpClient.Send() method is not supported on that platform.

Digging through the stack trace, and comparing against the AWS SDK source code, it looks like RefreshingAWSCredentials.GenerateNewCredentialsAsync is sending the rest of the call tree down a synchronous call path. Prior to that, all ***Async methods are being used. I suspect that if GenerateNewCredentialsAsync did not invoke the synchronous GenerateNewCredentials method then the call would use ***Async methods all the way down, and the exception would not be triggered.

I haven't found a way to work around this issue at the moment.

Amazon.Runtime.AmazonClientException: Error calling AssumeRole for role **REDACTED**
 ---> System.PlatformNotSupportedException: Operation is not supported on this platform.
   at System.Net.Http.HttpClientHandler.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpMessageInvoker.Send(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.Send(HttpRequestMessage request, HttpCompletionOption completionOption)
   at Amazon.Runtime.HttpWebRequestMessage.GetResponse()
   at Amazon.Runtime.Internal.HttpHandler`1[[System.Net.Http.HttpContent, System.Net.Http, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.Unmarshaller.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.Signer.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ChecksumHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CredentialsRetriever.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CompressionHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.BaseEndpointResolver.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.Marshaller.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.PipelineHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.MetricsHandler.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RuntimePipeline.InvokeSync(IExecutionContext executionContext)
   at Amazon.Runtime.AmazonServiceClient.Invoke[AssumeRoleResponse](AmazonWebServiceRequest request, InvokeOptionsBase options)
   at Amazon.SecurityToken.AmazonSecurityTokenServiceClient.AssumeRole(AssumeRoleRequest request)
   at Amazon.SecurityToken.AmazonSecurityTokenServiceClient.Amazon.Runtime.SharedInterfaces.ICoreAmazonSTS.CredentialsFromAssumeRoleAuthentication(String roleArn, String roleSessionName, AssumeRoleAWSCredentialsOptions options)
   --- End of inner exception stack trace ---
   at Amazon.SecurityToken.AmazonSecurityTokenServiceClient.Amazon.Runtime.SharedInterfaces.ICoreAmazonSTS.CredentialsFromAssumeRoleAuthentication(String roleArn, String roleSessionName, AssumeRoleAWSCredentialsOptions options)
   at Amazon.Runtime.AssumeRoleAWSCredentials.GenerateNewCredentials()
   at Amazon.Runtime.RefreshingAWSCredentials.<GenerateNewCredentialsAsync>b__16_0()
   at System.Threading.Tasks.Task`1[[Amazon.Runtime.RefreshingAWSCredentials.CredentialsRefreshState, AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]].InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__281_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   --- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of stack trace from previous location ---
   at Amazon.Runtime.RefreshingAWSCredentials.GetCredentialsAsync()
   at Amazon.Runtime.Internal.CredentialsRetriever.<InvokeAsync>d__7`1[[Amazon.EC2.Model.DescribeTagsResponse, AWSSDK.EC2, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]].MoveNext()
   at Amazon.Runtime.Internal.RetryHandler.<InvokeAsync>d__10`1[[Amazon.EC2.Model.DescribeTagsResponse, AWSSDK.EC2, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]].MoveNext()
   at Amazon.Runtime.Internal.RetryHandler.<InvokeAsync>d__10`1[[Amazon.EC2.Model.DescribeTagsResponse, AWSSDK.EC2, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]].MoveNext()
   at Amazon.Runtime.Internal.CallbackHandler.<InvokeAsync>d__9`1[[Amazon.EC2.Model.DescribeTagsResponse, AWSSDK.EC2, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]].MoveNext()
   at Amazon.Runtime.Internal.CallbackHandler.<InvokeAsync>d__9`1[[Amazon.EC2.Model.DescribeTagsResponse, AWSSDK.EC2, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]].MoveNext()
   at Amazon.Runtime.Internal.ErrorCallbackHandler.<InvokeAsync>d__5`1[[Amazon.EC2.Model.DescribeTagsResponse, AWSSDK.EC2, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]].MoveNext()
   at Amazon.Runtime.Internal.MetricsHandler.<InvokeAsync>d__1`1[[Amazon.EC2.Model.DescribeTagsResponse, AWSSDK.EC2, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]].MoveNext()

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

Calling DescribeTagsAsync would ultimately invoke HttpClient.SendAsync to perform HTTP communication with the AWS API.

Current Behavior

Calling DescribeTagsAsync ultimately invokes HttpClient.Send to perform HTTP communication with the AWS API.

Reproduction Steps

This is the bit that I'm unsure about. I don't know if the code path is being chosen because of how our credentials are set up. I'd appreciate some guidance on any additional information that's required to create a valid set of reproduction steps.

Possible Solution

Force descendants of RefreshingAWSCredentials to implement both GenerateNewCredentialsAsync and GenerateNewCredentials. Currently, only GenerateNewCredentials throws a NotImplementedException. Having both the async and sync versions of the method throw NotImplementException would make it clear that both methods need to be implemented. Alternatively, all descendants of RefreshingAWSCredentials could be audited to ensure that GenerateNewCredentialsAsync is overridden.

Additional Information/Context

No response

AWS .NET SDK and/or Package version used

Here are all the AWSSDK packages that are being referenced by the project that is encountering this issue.

  • AWSSDK.CloudWatch 3.7.103.63
  • AWSSDK.Core 3.7.303.10
  • AWSSDK.DynamoDBv2 3.7.102.33
  • AWSSDK.EC2 3.7.131.1
  • AWSSDK.IdentityManagement 3.7.100.120
  • AWSSDK.KeyManagementService 3.7.101.94
  • AWSSDK.RDS 3.7.117.6
  • AWSSDK.S3 3.7.307.11
  • AWSSDK.SecurityToken 3.7.101.54
  • AWSSDK.SimpleEmail 3.7.100.119
  • AWSSDK.SimpleNotificationService 3.7.101.55
  • AWSSDK.SQS 3.7.100.119
  • AWSSDK.SSO 3.7.100.119
  • AWSSDK.SSOOIDC 3.7.100.119

Targeted .NET Platform

.NET 8 Android

Operating System and version

Android

Metadata

Metadata

Assignees

Labels

bugThis issue is a bug.credentialsp2This is a standard priority issuepr/needs-reviewThis PR needs a review from a Member.v4

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions