jellycsc
jellycsc

Reputation: 12359

S3 Object Lambda WriteGetObjectResponse API returns 405 Method Not Allowed

The code is running on AWS Lambda Node.js 14 runtime using the AWS SDK for JavaScript version 2.868.0.

Here is the code snippet:

const AWS = require('aws-sdk');
const s3 = new AWS.S3();

exports.handler = async (event) => {
    const objectContent = event['getObjectContext'];
    const data = await s3.writeGetObjectResponse({
        Body: 'test',
        RequestRoute: objectContent['outputRoute'],
        RequestToken: objectContent['outputToken']
    }).promise();
    console.log(data);
    const response = {
        statusCode: 200
    };
    return response;
};

I have attached the following IAM policy to the Lambda role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowObjectLambdaAccess",
            "Action": [
                "s3-object-lambda:WriteGetObjectResponse"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

The function throws the following error on the line await s3.writeGetObjectResponse(...).promise():

2021-03-22T01:59:29.951Z    eb99f9a6-75c7-40ec-9f85-e19da084c42c    ERROR   Invoke Error    {
    "errorType": "MethodNotAllowed",
    "errorMessage": "The specified method is not allowed against this resource.",
    "code": "MethodNotAllowed",
    "message": "The specified method is not allowed against this resource.",
    "region": null,
    "time": "2021-03-22T01:59:29.891Z",
    "requestId": "C0FKZ5WSK027GPQW",
    "extendedRequestId": "+9rRhWJUPgIAmFupxXKrkAIWe5dXbi0vAacoN+/NlCQPgKzyZi0+mpevGMIVDDPo/1EYpo8Ntyk=",
    "statusCode": 405,
    "retryable": false,
    "retryDelay": 15.885104429810148,
    "stack": [
        "MethodNotAllowed: The specified method is not allowed against this resource.",
        "    at Request.extractError (/opt/nodejs/node_modules/aws-sdk/lib/services/s3.js:712:35)",
        "    at Request.callListeners (/opt/nodejs/node_modules/aws-sdk/lib/sequential_executor.js:106:20)",
        "    at Request.emit (/opt/nodejs/node_modules/aws-sdk/lib/sequential_executor.js:78:10)",
        "    at Request.emit (/opt/nodejs/node_modules/aws-sdk/lib/request.js:688:14)",
        "    at Request.transition (/opt/nodejs/node_modules/aws-sdk/lib/request.js:22:10)",
        "    at AcceptorStateMachine.runTo (/opt/nodejs/node_modules/aws-sdk/lib/state_machine.js:14:12)",
        "    at /opt/nodejs/node_modules/aws-sdk/lib/state_machine.js:26:10",
        "    at Request.<anonymous> (/opt/nodejs/node_modules/aws-sdk/lib/request.js:38:9)",
        "    at Request.<anonymous> (/opt/nodejs/node_modules/aws-sdk/lib/request.js:690:12)",
        "    at Request.callListeners (/opt/nodejs/node_modules/aws-sdk/lib/sequential_executor.js:116:18)"
    ]
}

Thanks in advance.

Upvotes: 0

Views: 2135

Answers (3)

Anelook
Anelook

Reputation: 1277

Update: the issue was fixed in 2.876.0. Please update to the latest version to avoid any need for the workaround.


I heard that the SDK team is working on the fix. The issue is related to the endpoint. You can actually see which endpoint is used if you console.log the result of s3.WriteGetObjectResponse(...).

For now you can use this workaround:

//Construct the client with an endpoint override so the request lands in the right place
const client = new AWS.S3({ region: "us-east-1", endpoint: "s3-object-lambda.us-east-1.amazonaws.com"});

// Override the signing service name from s3 to s3-object-lambda so the signatures are valid.
client.__proto__.api.endpointPrefix = "s3-object-lambda";
const data = await client.writeGetObjectResponse({
    Body: 'test',
    RequestRoute: objectContent['outputRoute'],
    RequestToken: objectContent['outputToken']
}).promise();

I run into exact same issue while experimenting with the feature and the workaround worked well for me.

In case it turns out to be useful I combined an article based on the learnings, can be used as a small tutorial to S3 Object Lambda.

Upvotes: 2

Michele Riso
Michele Riso

Reputation: 1

There is a workaround to temporary fix this issue until the bug is not solved

/** START Workaround for bug #3675 **/
const s3 = new AWS.S3({ region: "us-east-1", endpoint: "s3-object-lambda.us-east-1.amazonaws.com" });
s3.__proto__.api.endpointPrefix = "s3-object-lambda";
/** END Workaround for bug #3675 **/

I've documented the usage in my medium blog if that can help

Upvotes: 0

Michele Riso
Michele Riso

Reputation: 1

I have opened a bug issue on AWS SDK Github https://github.com/aws/aws-sdk-js/issues/3675 as it seems to be an SDK problem

Upvotes: 0

Related Questions