142

I'm seeing the below error from my lambda function when I drop a file.csv into an S3 bucket. The file is not large and I even added a 60 second sleep prior to opening the file for reading, but for some reason the file has the extra ".6CEdFe7C" appended to it. Why is that?

[Errno 30] Read-only file system: u'/file.csv.6CEdFe7C': IOError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 75, in lambda_handler
s3.download_file(bucket, key, filepath)
File "/var/runtime/boto3/s3/inject.py", line 104, in download_file
extra_args=ExtraArgs, callback=Callback)
File "/var/runtime/boto3/s3/transfer.py", line 670, in download_file
extra_args, callback)
File "/var/runtime/boto3/s3/transfer.py", line 685, in _download_file
self._get_object(bucket, key, filename, extra_args, callback)
File "/var/runtime/boto3/s3/transfer.py", line 709, in _get_object
extra_args, callback)
File "/var/runtime/boto3/s3/transfer.py", line 723, in _do_get_object
with self._osutil.open(filename, 'wb') as f:
File "/var/runtime/boto3/s3/transfer.py", line 332, in open
return open(filename, mode)
IOError: [Errno 30] Read-only file system: u'/file.csv.6CEdFe7C'

Code:

def lambda_handler(event, context):

    s3_response = {}
    counter = 0
    event_records = event.get("Records", [])

    s3_items = []
    for event_record in event_records:
        if "s3" in event_record:
            bucket = event_record["s3"]["bucket"]["name"]
            key = event_record["s3"]["object"]["key"]
            filepath = '/' + key
            print(bucket)
            print(key)
            print(filepath)
            s3.download_file(bucket, key, filepath)

The result of the above is:

mytestbucket
file.csv
/file.csv
[Errno 30] Read-only file system: u'/file.csv.6CEdFe7C'

If the key/file is "file.csv", then why does the s3.download_file method try to download "file.csv.6CEdFe7C"? I'm guessing when the function is triggered, the file is file.csv.xxxxx but by the time it gets to line 75, the file is renamed to file.csv?

2
  • Dump not equal to read ! So your file on temp folder (or in ram) need dump not self._osutil.open(filename, 'wb') as f:, only allowed rbetc. So need handle source file before processing. Commented Sep 8, 2016 at 7:42
  • @user1530318, would you mind to mark the top answer as correct? It seems all right. Commented Apr 28, 2018 at 17:52

5 Answers 5

385

Only /tmp seems to be writable in AWS Lambda.

Therefore this would work:

filepath = '/tmp/' + key

References:

Sign up to request clarification or add additional context in comments.

6 Comments

In my similar situation (writing File to user.dir: /<filename>), but with JAVA & a 3.8MB .zip Object, this warning printed right before my ["Read-only"] SDKClientException printed (but it was happily resolved after using /tmp/ Solution instead! Probably because the S3ObjectInputStream died as soon as it couldn't get the /<filename> prior): WARNING: Not all bytes were read from the S3ObjectInputStream, aborting HTTP connection. This is likely an error and may result in sub-optimal behavior. Request only the bytes you need via a ranged GET or drain the input stream after use.
Tried the same but givig the error OSError: [Errno 30] Read-only file system: 'tmp/token.json'\n"
This is odd, but writing without '/tmp' worked for me for months. Until today, when it broke. Thanks
Hey, do you know what happens to a file/folder created in /tmp/ after the function ends? Is it permanently deleted?
@Dubraven no files whatsoever in Lambda are expected to persist. I'm not sure if it's defined how often they're deleted, but you should design with the expectation that after your function call is done, your files are deleted.
|
25

According to http://boto3.readthedocs.io/en/latest/guide/s3-example-download-file.html

The example shows how to use the first parameter for the cloud name and the second parameter for the local path to be downloaded.

enter image description here

in other hand, the amazaon docs, says enter image description here

Thus, we have 512 MB for create files. Here is my code on lambda aws, it works like charm.

.download_file(Key=nombre_archivo,Filename='/tmp/{}'.format(nuevo_nombre))

3 Comments

cool, that's your code, what about it? If your answer solves the question, please add an explanation why it works. If it doesn't, please delete it.
Corrected, let me know if I have to set more information
Even if it is just an example, please, don't put code in an image. While doing that, please fix the typos in your answer. Overall however, the answer got better. :-D
1

I noticed when I uploaded a code for lambda directly as a zip file I was able to write only to /tmp folder, but when uploaded code from S3 I was able to write to the project root folder too.

1 Comment

Do you have an example?
1

"""lambda function only allows to write in /tmp path.

simply do this at first. it will works like a charm. """

import os

os.chdir("/tmp/")

Comments

0

Also for C# works perfect :

using (var fileStream = File.Create("/tmp/" + fName))
{
   str.Seek(0, SeekOrigin.Begin);
   str.CopyTo(fileStream);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.