serverless/serverless-python-requirements

Error "Could not unzip uploaded file" when using Lambda Layer

j-adamczyk opened this issue · 2 comments

I am using Serverless to deploy Python Lambda function triggered with Kinesis. I use serverless-python-requirements to pack a few requirements.

I get an error:

? Do you want to deploy now? Yes

Deploying data-events to stage dev (eu-central-1)
[data-package-external] Symlinking packages/psycopg2
[data-package-external] Symlinking config/dev.yml
[data-package-external] is complete
Config not created, locally skipping
Config not created, locally skipping

✖ Stack data-events-dev failed to deploy (17s)
Environment: linux, node 18.5.0, framework 3.20.0 (local), plugin 6.2.2, SDK 4.3.2
Credentials: Local, "dev" profile
Docs:        docs.serverless.com
Support:     forum.serverless.com
Bugs:        github.com/serverless/serverless/issues

Error:
UPDATE_FAILED: PythonRequirementsLambdaLayer (AWS::Lambda::LayerVersion)
Could not unzip uploaded file. Please check your file, then try to upload again. (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: 741b245d-ab82-49de-8a3f-4a45136fb520; Proxy: null)

I use Poetry, my pyproject.toml:

[tool.poetry]
name = "event_processing"
version = "1.0.0"
description = ""
authors = ["Data team"]

[tool.poetry.dependencies]
python = "^3.9"

arrow = "*"
aws-psycopg2 = "*"
fluent-logger = "*"
pyyaml = "*"
requests = "*"

[tool.poetry.dev-dependencies]
black = "*"
boto3 = "*"
coverage = "*"
freezegun = "*"
mock = "*"
nose = "*"
pre-commit = "*"
pylint = "*"
pytest = "*"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

My serverless.yml:

functions:
  kinesisEvents:
    handler: events_processing.lambda_handler
    name: kinesis-events-${self:provider.stage}
    layers:
      - Ref: PythonRequirementsLambdaLayer
    package: {}
    maximumRetryAttempts: 2
    events:
      - stream:
          type: kinesis
          arn:
            Fn::Join:
              - ':'
              - - arn
                - aws
                - kinesis
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - stream/events_${self:provider.stage}
          batchSize: 50
          startingPosition: LATEST
    environment:
      API_PASSWORD: ${ssm:/${self:provider.stage}/api_password}
      CRM_SERVICE_PASSWORD: ${ssm:/${self:provider.stage}/crm_service_password}
    vpc:
      securityGroupIds: ${file(config/${self:provider.stage}.yml):AWS_SECURITY_GROUP_IDS}
      subnetIds: ${file(config/${self:provider.stage}.yml):AWS_SUBNET_IDS}

I think this error started to show up when I changed my config file (config/${self:provider.stage}.yml) from JSON to YAML, but I'm not sure. What can I do about this? How can I even debug this? Can this plugin output the ZIP file locally, or can it be found somewhere on AWS?

EDIT: I encounter this error only when using layers, i.e. with PythonRequirementsLambdaLayer and layer: true. When using without it, this works ok.

Any luck resolving this issue? I'm seeing the same thing just after I added numpy to requirements.txt, and sure enough I cannot unzip the file:

$ unzip -l .serverless/pythonRequirements.zip 
Archive:  .serverless/pythonRequirements.zip
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of .serverless/pythonRequirements.zip or
        .serverless/pythonRequirements.zip.zip, and cannot find .serverless/pythonRequirements.zip.ZIP, period.

@kristinlindquist clearing local Serverless cache fixed this for me