title: Java myHandler S3 Put Client Timeout in Lambda
body: <p>Wondering if someone here has some insight. I can't figure out what may be blocking my lambda function from writing to s3, it seems to be timing out. I have given the role for the lambda full s3 access rights but it shouldn't be required because I pass credentials on the classpath.</p>
  
  <p>This works locally when I run from a fat jar:</p>
  
  <pre><code>$ java -cp dronze-app-fat.jar com.dronze.aws.lambda.HelloAwsLambda 
  
  trying to write to bucket.
  {"result":"SUCCEED"}
  </code></pre>
  
  <p>But hangs in lambda.</p>
  
  <pre><code>START RequestId: 1dbeabac-eff1-11e5-a1ca-611b19003683 Version: $LATEST 
  initializing s3Client.
  trying to write to bucket.
  END RequestId: 1dbeabac-eff1-11e5-a1ca-611b19003683 
  REPORT RequestId: 1dbeabac-eff1-11e5-a1ca-611b19003683  Duration: 15002.75 ms   Billed Duration: 15000 ms Memory Size: 512 MB   Max Memory Used: 107 MB  
  2016-03-22T05:44:45.228Z 1dbeabac-eff1-11e5-a1ca-611b19003683 Task timed out after 15.00 seconds    
  Mar 22, 2016 3:46:24 PM com.amazonaws.http.AmazonHttpClient executeHelper 
  INFO: Unable to execute HTTP request: connect timed out 
  java.net.SocketTimeoutException: connect timed out 
  at java.net.PlainSocketImpl.socketConnect(Native Method) 
  at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) 
  at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) 
  at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) 
  at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) 
  </code></pre>
  
  <p>The lambda method just writes an s3 json document:</p>
  
  <pre><code>private void saveToS3(String jsonDocument, String bucketName, String keyName, LambdaLogger logger) { 
      if(s3Client == null){
          logger.log("initializing s3Client.");
  
          ClientConfiguration config = new ClientConfiguration();
          config.setConnectionTimeout(14000);
  
          s3Client = new AmazonS3Client(
                  new ClasspathPropertiesFileCredentialsProvider(
                  "application-prod.properties"), config);
  
          s3Client.setRegion(Region.getRegion(Regions.US_WEST_2));
      }
  
      try {
          InputStream stream = new ByteArrayInputStream(
                  jsonDocument.getBytes(StandardCharsets.UTF_8));
          String bucket = bucketName;
          ObjectMetadata metadata = new ObjectMetadata();
          metadata.setContentType("application/json");
          metadata.setContentDisposition("attachment; filename=\"" + keyName);
          metadata.setContentLength(jsonDocument.length());
  
          PutObjectRequest put = new PutObjectRequest(bucket, keyName,
                  stream, metadata);
          put.setStorageClass(StorageClass.ReducedRedundancy);
          put.setMetadata(metadata);
  
          logger.log("trying to write to bucket.");
          s3Client.putObject(put);
  
      } catch (AmazonServiceException ase) {
          logger.log("Caught an AmazonServiceException, which "
                  + "means your request made it "
                  + "to Amazon S3, but was rejected with an error response"
                  + " for some reason.");
          logger.log("Error Message:    " + ase.getMessage());
          logger.log("HTTP Status Code: " + ase.getStatusCode());
          logger.log("AWS Error Code:   " + ase.getErrorCode());
          logger.log("Error Type:       " + ase.getErrorType());
          logger.log("Request ID:       " + ase.getRequestId());
      } catch (AmazonClientException ace) {
          logger.log("Caught an AmazonClientException, which "
                  + "means the client encountered "
                  + "an internal error while trying to "
                  + "communicate with S3, "
                  + "such as not being able to access the network.");
          logger.log("Error Message: " + ace.getMessage());
      }
  }
  </code></pre>
  
  <p>The behaviour seems to be something related to the role of the lambda function, or a security group being able to connect to s3 (I didn't think lambda have security groups) but something is blocking the s3 client put even though the role allows it:</p>
  
  <pre><code>{
      "Version": "2012-10-17",
      "Statement": [
          {
              "Effect": "Allow",
              "Action": [
                  "logs:CreateLogGroup",
                  "logs:CreateLogStream",
                  "logs:PutLogEvents"
              ],
              "Resource": "arn:aws:logs:*:*:*"
          },
          {
              "Effect": "Allow",
              "Action": [
                  "ec2:CreateNetworkInterface",
                  "ec2:DescribeNetworkInterfaces",
                  "ec2:DetachNetworkInterface",
                  "ec2:DeleteNetworkInterface"
              ],
              "Resource": "*"
          },
          {
           "Effect":"Allow",
           "Action":[
              "s3:PutObject",
              "s3:GetObject",
              "s3:DeleteObject"
           ],
           "Resource":"arn:aws:s3:::dronze.lambda.b283/*"
        }
      ]
  }       
  </code></pre>
  
  <p>I have bumped up memory and timeouts to bizarre levels and it still is blocked. This seems to be a networking issue not resources. Any insight on a solution is greatly appreciated.</p>