51

Getting error fork/exec /var/task/main: no such file or directory while executing lambda function.

I am using windows platform to run and build code in Go.

I have done following steps to deploy go aws-lambda handler:

  1. Written code in go language with VSCode in windows platform
  2. Build project with : go build main.go
  3. Convert main.exe to main.zip
  4. Uploaded main.zip with handler name main aws-lambda fuction using aws console account
  5. Created test event to test lambda function
  6. Got error "fork/exec /var/task/main: no such file or directory while executing lambda function"
package main

import (
    "fmt"

    "github.com/aws/aws-lambda-go/lambda"
)

// Request represents the requested object
type Request struct {
    ID    int    `json:"ID"`
    Value string `json:"Value"`
}

// Response represents the Response object
type Response struct {
    Message string `json:"Message"`
    Ok      bool   `json:"Ok"`
}

// Handler represents the Handler of lambda
func Handler(request Request) (Response, error) {
    return Response{
        Message: fmt.Sprint("Process Request Id %f", request.ID),
        Ok:      true,
    }, nil
}

func main() {
    lambda.Start(Handler)
}

build command

go build main.go

Detail Error in AWS console

{
  "errorMessage": "fork/exec /var/task/main: no such file or directory",
  "errorType": "PathError"
}

Log Output in AWS console

START RequestId: 9ef206ed-5538-407a-acf0-06673bacf2d7 Version: $LATEST
fork/exec /var/task/main: no such file or directory: PathError
null
END RequestId: 9ef206ed-5538-407a-acf0-06673bacf2d7
REPORT RequestId: 9ef206ed-5538-407a-acf0-06673bacf2d7  Duration: 0.64 ms   Billed Duration: 100 ms Memory Size: 512 MB Max Memory Used: 31 MB  Init Duration: 1.49 ms
colm.anseo
  • 19,337
  • 4
  • 43
  • 52
Pooja K Bhatt
  • 979
  • 2
  • 10
  • 18

16 Answers16

45

In my case the problem was default setted handler to 'hello' function.

Needed to change it to 'main' via AWS Lambda view panel -> Basic Settings -> Edit.

AWS Lambda function

mch.zawalski
  • 558
  • 4
  • 5
28

Run following commands in command prompt

set GOOS=linux
set GOARCH=amd64
set CGO_ENABLED=0

After this , build your project and upload zip file to aws console lambda

like this

GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o main main.go

Reference Link : https://github.com/aws/aws-lambda-go

Conor
  • 426
  • 7
  • 22
Pooja K Bhatt
  • 979
  • 2
  • 10
  • 18
  • 22
    While it wasn't a problem in this example, I think it might be worth pointing out that the executable has to be called "main", not just the function in the code. I found this out the hard way when following the instructions above. – David Fulton Nov 01 '19 at 16:45
  • Yes you are right, that the executable has to be called "main", not just the function in the code. – Pooja K Bhatt Nov 05 '19 at 10:17
  • After the first step I only had to do 'go build -o main main.go', zipped the main file that appeared and uploaded to AWS. That solved my issue at least – Charlie Araya Oct 20 '21 at 14:46
  • Yes the executable name is key - but the name doesn't strictly need to be `main`. One can change the `Handler` name on the AWS side to another executable name. – colm.anseo Jan 02 '22 at 17:32
12

There are two reasons can happen:

  1. You did't use GOOS=linux GOARCH=amd64 with go build, so try:

    GOOS=linux GOARCH=amd64 go build -o main main.go

  2. You used to build this programm some CI function with golang-alpine base image, so try to use full golang image instead.

Wishmaster
  • 1,102
  • 14
  • 20
10

Recently I was facing similar issue, and I solved it. As the error says it s finding executable with handle name, so you should name your executable same as handler.

Follow these steps and your will not get this error, I am using PowerShell

> go.exe get -u github.com/aws/aws-lambda-go/cmd/build-lambda-zip # If you do not this have utility earlier
> $env:GOOS = "linux"
> $env:GOARCH = "amd64"
> $env:CGO_ENABLED = "0"
> go build -o .\Handler .\main.go # considering your are in the same directory where your main.go or handler code is present
> ~\Go\Bin\build-lambda-zip.exe -o .\Handler.zip .\Handler

Upload this code, and change handler name to Handler(name of the executable that you created above) enter image description here

Let me know if this helps.

Psp360
  • 123
  • 1
  • 8
  • Naming the Handler in AWS lambda function 'Handler' is a important step, once the steps mentioned above have been followed. – coder kemp Jan 20 '21 at 12:25
3

In my embarrasing case I was zipping the folder from outside so the path in the zip I was uploading was 'folder/main'

drodsou
  • 2,970
  • 1
  • 21
  • 15
  • I was doing this exact thing... it happens to the best of us lol. Also, good idea to make sure all names match up as well o.O – afreeland Mar 10 '23 at 22:31
3

You can find the description when you click AWS Lambda > Functions > <Your function name> > Handler info enter image description here

You can tell the Lambda runtime which handler method to invoke by setting the handler parameter on your function's configuration.

When you configure a function in Go, the value of the handler setting is the executable file name. For example, using Handler would call the function in the package main of the Handler executable file.

It means that your file which has a handler function is not necessarily named main.go. My Handler on AWS is hello and I use this command to create executable file GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o hello hello.go

Here is my case. I am learning Terraform to deploy AWS Lambda function. I am following an terraform official document to deploy a hello function. The page guides me to create a function using Node.js and I rewrite it using Go.

Here is my modified part of main.tf.

resource "aws_lambda_function" "hello_world" {
  function_name = "HelloWorld"
  s3_bucket = aws_s3_bucket.lambda_bucket.id
  s3_key    = aws_s3_object.lambda_hello_world.key
  runtime = "go1.x"
  handler = "hello"
  source_code_hash = data.archive_file.lambda_hello_world.output_base64sha256
  role = aws_iam_role.lambda_exec.arn
}

I deleted the hello.js file and created the hello.go file.

My hello.go is the same as AWS example

package main

import (
    "fmt"
    "context"
    "github.com/aws/aws-lambda-go/lambda"
)
type MyEvent struct {
    Name string `json:"name"`
}

func HandleRequest(ctx context.Context, name MyEvent) (string, error) 
{
    return fmt.Sprintf("Hello %s!", name.Name ), nil
}

func main() {
    lambda.Start(HandleRequest)
}

After deploying the lambda function using terraform, we can verify it.

% aws lambda invoke --region=us-east-1 --function-name=HelloWorld response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

I hope this is helpful.

Henry S.
  • 432
  • 1
  • 3
  • 8
1

My issue (I think) was the zipping tool / GOOS=windows was set wrong.

Zip Go file using AWS Lambda Tool

My setup is windows + following a golang tutorial. Published to lambda, all appeared fine, got the error and was correctly named and built etc.

I think it's the zipping tool, using build-lambda-zip and now it works for me. Note: I tried using another command to get the tool go.exe get -u github.com/aws/aws-lambda-go/cmd/build-lambda-zip however this didn't actually get the tool for me.

Hopefully this saves someone else half an hour of googling

Ben Moses
  • 11
  • 1
1

What the accepted answer says, use environmental variables. But note the following: Using Powershell (Jetbrains IDEs use it as well) requires different commands than cmd (see aws documentation). Namely, for cmd:

set GOOS=linux
set GOARCH=amd64
set CGO_ENABLED=0

for Powershell:

$env:GOOS = "linux"
$env:GOARCH = "amd64"
$env:CGO_ENABLED = "0"

Also the Go program needs to have package main as well as a main() method (doc). In the AWS runtime config the handler name needs to be named like the build file. It doesnt matter how the .zip or .go is named.

  • thank you -- i had my suspicions but the only thing I was missing is my package name also had to match the handler :). Thanks! – howard Jul 25 '23 at 09:02
0

In my case it was related to my Go setting.

As I use Go Version Manager, I had to run the following to specify the right Go path before compiling my project.

gvm use go1.x.x

Proceed to compile then deploy.

yoges nsamy
  • 1,275
  • 1
  • 16
  • 29
0

My case was a strange one, but I'll leave it here in case someone needs it.

I built my executable in a Docker container and then used Docker cp to put the file in a local directory. Then I zipped the executable and deployed it.

Apparently, Docker cp creates a symlink-like file rather than an actual file, so it just wouldn't work.

My solution was just to use sudo cp and copy the executable as another file, which created a physical file, and deployed that instead.

Luke-zhang-04
  • 782
  • 7
  • 11
0

This error has nothing to do with the program; it's a configuration issue. Please try to give the complied go file name in the lambda console under Go Runtime settings -

In my case my go lambda compiled file is test so configured Handler as test and it worked for me.

Example Configuration

jeffrey
  • 965
  • 14
  • 25
0

In my case, the solution is very simple.

I was wrong with the command build. what I did was go build . instead of go build main.go

the zip file should be main.zip.

and the handler info section in console AWS should be named main. not handler because lambda calls the main function first

rulisastra
  • 311
  • 1
  • 2
  • 14
0

If deploying with SAM cli, make sure to run "sam build" before the "sam deploy"

trex
  • 325
  • 3
  • 8
0

In my case this had to do with the image I was using to build the go binaries. I switched from using alpine to using amazon linux 2 and the problem was solved.

Derick F
  • 2,749
  • 3
  • 20
  • 30
0

setting environment variable CGO_ENABLED to 0 solved my problem, this is when using sam local start-api to locally test endpoint

0

I use sam for locally debug use and hit this issue too, then I found I set the wrong path in my template.yaml, actually, after run GOOS=linux GOARCH=arm64 go build -gcflags "all=-N -l" -o bin/bootstrap ., there is a bin folder generated in my root path, then I need to add this path to CodeUri property in template.yaml file, such as(I use MacOs with M1 chip):

Resources:
  YourAppName:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./bin
      Handler: bootstrap
      Runtime: go1.x
      Architectures:
        - x86_64
      Environment:
        Variables:
          ENVIRONMENT_NAME: YOUR_ENV_NAME
      Events:
        ScheduleEvent:
          Type: Schedule
          Properties:
            Schedule: "rate(1 minute)"
Rt.Tong
  • 196
  • 3
  • 5