2

I am trying to save a file to an S3 bucket. I am copying the file to a temp location just to prove (to me) the file exists and is accessible. Of course the copy works without issue.

The last line keeps throwing an exception and the details say "Object reference not set to an instance of an object".

File.Copy(fullFilePath, "C:\\Temp\\" + fullFileName);

IAmazonS3 client = null;
if (Session["s3Client"] != null) {
    client = (IAmazonS3)Session["s3Client"];
} else {
    client = new AmazonS3Client(RegionEndpoint.GetBySystemName(AWS_REGION));
} // if

PutObjectRequest putRequest = new PutObjectRequest {
    BucketName = S3_BUCKET_NAME,
    Key = fullFileName
};

using (FileStream stream = new FileStream(fullFilePath, FileMode.Open)) {
    putRequest.InputStream = stream;

    // Put object
    PutObjectResponse response = client.PutObject(putRequest);
}

I have tried a few things with the S3 call:

  1. Different key (tried the word 'blah')
  2. Different bucket
  3. Sending the file as a path rather than a stream

There is not a lot else for me to try since I am really only providing 3 fields.

I am trying to leave authentication outside of the code so the host machine can control it.

Any ideas?

Thanks a lot.

Edit:

at Amazon.Runtime.DefaultInstanceProfileAWSCredentials.FetchCredentials()
at Amazon.Runtime.DefaultInstanceProfileAWSCredentials.GetCredentials()
at Amazon.Runtime.Internal.CredentialsRetriever.PreInvoke(IExecutionContext executionContext)
at Amazon.Runtime.Internal.CredentialsRetriever.InvokeSync(IExecutionContext executionContext)
at Amazon.Runtime.Internal.RetryHandler.InvokeSync(IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeSync(IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeSync(IExecutionContext executionContext)
at Amazon.S3.Internal.AmazonS3ExceptionHandler.InvokeSync(IExecutionContext executionContext)
at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeSync(IExecutionContext executionContext)
at Amazon.Runtime.Internal.MetricsHandler.InvokeSync(IExecutionContext executionContext)
at Amazon.Runtime.Internal.RuntimePipeline.InvokeSync(IExecutionContext executionContext)
at Amazon.Runtime.AmazonServiceClient.Invoke[TResponse](AmazonWebServiceRequest request, InvokeOptionsBase options)
at MyCode.aspx.cs:line 260
Garet Jax
  • 1,091
  • 3
  • 17
  • 37
  • 1
    Please check the **stack trace** of the exception to determine _where exactly_ the exception was raised. – René Vogt Jun 18 '19 at 16:55
  • Just a c# observation...if `putRequest.InputStream = stream;` didn't throw an exception, then the `null` has to be client. – Clay Jun 18 '19 at 17:03
  • ...and none of the things you tried would do *anything* about that ;-) – Clay Jun 18 '19 at 17:04
  • @René Vogt - Good thinking. The stack trace is much more useful. It is clearly not using the default configuration for authentication. I will need to provide auth parameters separately. – Garet Jax Jun 18 '19 at 17:06
  • @Clay - I have validated that the obvious things aren't null. – Garet Jax Jun 18 '19 at 17:07
  • @René Vogt - Please unmark this as duplicate. None of my objects are null. This is happening inside of the AWS APIs. – Garet Jax Jun 18 '19 at 18:27
  • 1
    @GaretJax: decompile their API using any decompiler (IlSpy would do) and look into the implementation. Check how they acquire credentials and what you can do about it. It could even be something simple (e.g. you miss a proper configuration key/value). – Wiktor Zychla Jun 18 '19 at 19:17
  • 1
    The stack trace helps ;-) – Clay Jun 18 '19 at 21:11
  • Not sure why this was down voted as a question - I thought it was an exemplary question. :-) – Garet Jax Jun 18 '19 at 23:26

1 Answers1

3

This problem all had to do with IIS permissions. AWS was trying to access the credentials through entries in the web.config file:

<configSections>
  <section name="aws" type="Amazon.AWSSection, AWSSDK.Core"/>
</configSections>
<aws profileName="default" profilesLocation="C:\Users\Administrator\.aws\credentials"/>

When IIS is running, it doesn't have access to the credentials file listed above.

The solution was to give the defaultAppPool read access to the file. I did this by adding 'IIS APPPOOL\defaultAppPool' to the security tab of the directory making sure it had read access.

enter image description here

The error from AWS is atrocious. A proper error message and I would have saved a lot of time.

Garet Jax
  • 1,091
  • 3
  • 17
  • 37