title: AWS S3 - com.amazonaws.AmazonServiceException: Request ARN is invalid
body: <p>I'm trying to make my android app download images from AWS S3. However, the following exception keeps coming up:</p>
  
  <pre><code>com.amazonaws.AmazonServiceException: Request ARN is invalid (Service: AWSSecurityTokenService; Status Code: 400; Error Code: ValidationError; Request ID: 3481bd5f-1db2-11e5-8442-cb6f713243b6)
              at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:710)
              at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:385)
              at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:196)
              at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.invoke(AWSSecurityTokenServiceClient.java:875)
              at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.assumeRoleWithWebIdentity(AWSSecurityTokenServiceClient.java:496)
              at com.amazonaws.auth.CognitoCredentialsProvider.populateCredentialsWithSts(CognitoCredentialsProvider.java:671)
              at com.amazonaws.auth.CognitoCredentialsProvider.startSession(CognitoCredentialsProvider.java:555)
              at com.amazonaws.auth.CognitoCredentialsProvider.refresh(CognitoCredentialsProvider.java:503)
              at com.application.app.utils.helper.S3Utils.getCredProvider(S3Utils.java:35)
              at com.application.app.utils.helper.S3Utils.getS3Client(S3Utils.java:45)
              at com.application.app.integration.volley.CustomImageRequest.parseNetworkError(CustomImageRequest.java:73)
              at com.android.volley.NetworkDispatcher.parseAndDeliverNetworkError(NetworkDispatcher.java:144)
              at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:135)
  </code></pre>
  
  <p>I have a bucket and an identity pool. Also, created required roles.</p>
  
  <p>My Cognito_APPUnauth_Role has the following INLINE POLICY:</p>
  
  <pre><code>{
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "Stmt1435504517000",
              "Effect": "Allow",
              "Action": [
                  "s3:GetObject",
                  "s3:ListBucket"
              ],
              "Resource": [
                  "arn:aws:s3:::mybucket/*"
              ]
          }
      ]
  }
  </code></pre>
  
  <p>I have a java class named S3Utils that has some helper methods.</p>
  
  <pre><code>public class S3Utils {
      private static AmazonS3Client sS3Client;
  
      private static CognitoCachingCredentialsProvider sCredProvider;
  
      public static CognitoCachingCredentialsProvider getCredProvider(Context context){
          if (sCredProvider == null) {
              sCredProvider = new CognitoCachingCredentialsProvider(
                      context,
                      Definitions.AWS_ACCOUNT_ID,
                      Definitions.COGNITO_POOL_ID,
                      Definitions.COGNITO_ROLE_UNAUTH,
                      null,
                      Regions.US_EAST_1
              );
          }
  
          sCredProvider.refresh();
          return sCredProvider;
      }
  
      public static String getPrefix(Context context) {
          return getCredProvider(context).getIdentityId() + "/";
      }
  
      public static AmazonS3Client getS3Client(Context context) {
          if (sS3Client == null) {
              sS3Client = new AmazonS3Client(getCredProvider(context));
          }
          return sS3Client;
      }
  
      public static String getFileName(String path) {
          return path.substring(path.lastIndexOf("/") + 1);
      }
  
      public static boolean doesBucketExist() {
          return sS3Client.doesBucketExist(Definitions.BUCKET_NAME.toLowerCase(Locale.US));
      }
  
      public static void createBucket() {
          sS3Client.createBucket(Definitions.BUCKET_NAME.toLowerCase(Locale.US));
      }
  
      public static void deleteBucket() {
          String name = Definitions.BUCKET_NAME.toLowerCase(Locale.US);
          List&lt;S3ObjectSummary&gt; objData = sS3Client.listObjects(name).getObjectSummaries();
          if (objData.size() &gt; 0) {
              DeleteObjectsRequest emptyBucket = new DeleteObjectsRequest(name);
              List&lt;DeleteObjectsRequest.KeyVersion&gt; keyList = new ArrayList&lt;DeleteObjectsRequest.KeyVersion&gt;();
              for (S3ObjectSummary summary : objData) {
                  keyList.add(new DeleteObjectsRequest.KeyVersion(summary.getKey()));
              }
              emptyBucket.withKeys(keyList);
              sS3Client.deleteObjects(emptyBucket);
          }
          sS3Client.deleteBucket(name);
      }
  }
  </code></pre>
  
  <p>Part of the method where the exception occurs, in CustomImageRequest.java:</p>
  
  <pre><code>s3Client = S3Utils.getS3Client(context);
              ObjectListing objects = s3Client.listObjects(new ListObjectsRequest().withBucketName(Definitions.BUCKET_NAME).withPrefix(this.urlToRetrieve));
              List&lt;S3ObjectSummary&gt; objectSummaries = objects.getObjectSummaries();
              //This isn't just an id, it is a full picture name in S3 bucket.
              for (S3ObjectSummary summary : objectSummaries)
              {
                  String key = summary.getKey();
                  if (!key.equals(this.urlToRetrieve)) continue;
                  S3ObjectInputStream content = s3Client.getObject(Definitions.BUCKET_NAME, key).getObjectContent();
                  try {
                      this.s3Image = IOUtils.toByteArray(content);
  
                  } catch (IOException e) {
                  }
  
                  return new Object();
              }
  </code></pre>
  
  <p>What am I doing wrong that causes this exception to be thrown every time. Thanks in advance.</p>