Upgrading to Serverless Framework v3

Serverless Framework v3 contains a few breaking changes that may impact some projects.

This guide helps users upgrade from Serverless Framework v2 to v3.

Am I impacted by breaking changes?

Serverless Framework v2 signals any deprecated feature via a deprecation warning. The simplest way to upgrade to v3 is to:

  1. Upgrade Serverless Framework to the latest v2 version
  2. Run serverless commands in the project to see if there are any deprecation warnings

Projects that do not have any deprecations can be immediately upgraded to v3. Projects that have deprecation warnings should first solve these deprecations, then upgrade to v3.

What about plugins?

We have worked with the most popular plugins to make sure they support Serverless Framework v3. As long as a project has no deprecations, it can be safely upgraded to v3.

That being said, some plugins need to be updated to be installable with v3. In most cases, it is a matter of allowing the plugin to be installed with Serverless Framework v3 in package.json (updating the peerDependencies requirement). Feel free to open an issue or pull request in the GitHub repository of the plugin.

Upgrading to v3

First, upgrade to the latest v2 version and make sure that you do not get any deprecation warning when running serverless commands.

Then, to upgrade to Serverless Framework v3, run:

npm install -g serverless

If you installed serverless as a standalone binary, run the following command instead:

  • MacOS/Linux standalone binary: serverless upgrade --major
  • Windows: choco upgrade serverless

Update frameworkVersion setting for v3

In all projects that you want to upgrade to Serverless Framework v3, you need to make sure that frameworkVersion specified in project configuration allows v3 version. You can achieve it by setting it in the following manner:

frameworkVersion: '3'

Using v2 and v3 in different projects

It is possible to use v3 in some projects and v2 in other projects. To achieve that, install the Serverless Framework locally via NPM (npm i --save-dev serverless).

There are 2 scenarios:

  • Using v3 globally, and v2 in specific projects.

    This is the simplest. Upgrade the global version to v3, and install v2 in specific projects (via NPM). The serverless command will automatically run the correct version (v3 can run v2).

  • Using v2 globally, and v3 in specific projects.

    To achieve that, install v3 in specific projects (via NPM). Then, use serverless for v2 projects, and npx serverless for v3 projects.

Breaking changes

You will find below a complete list of all breaking changes. All those breaking changes were signaled via deprecation messages in Serverless Framework v2.

CLI commands and options

The serverless CLI no longer runs on Node v10 because that version is obsolete: upgrade to v12.13.0 (LTS) or greater to run serverless on your machine.

The serverless CLI used to accept free-form CLI options. This feature was deprecated and has been removed. The main reason is that this prevented us from detecting typos in options, which sometimes created unexpected situations and overall a bad user experience. You can use the --param option as a replacement, for example:

# Will no longer work in v3:
serverless deploy --foo=bar

# Alternative in v3.3 and greater:
serverless deploy --param="foo=bar"

In the example above, the ${opt:foo} variable must be replaced with ${param:foo} in the service configuration.

Learn more about this change.

Additionally, all CLI options must now be passed at the end of the commands:

# Will no longer work in v3:
serverless --verbose deploy

# Correct syntax:
serverless deploy --verbose

This change makes the CLI much more robust at detecting arguments from options and their values.

On that note, the -v option is no longer recognized (it was ambiguous with --version): use the full --verbose option instead.

When the serverless CLI is installed globally and locally (in the project’s node_modules), the local version will always be used. It is no longer possible to disable that behavior (learn more).

The serverless deploy command internals for AWS provider has been changed and now use change sets. Due to that, the required IAM permissions for successfully running deployments have changed and now also include the following actions:

- cloudformation:CreateChangeSet
- cloudformation:DeleteChangeSet
- cloudformation:DescribeChangeSet
- cloudformation:ExecuteChangeSet

Finally, the serverless studio command has been removed: that feature was deprecated and is no longer available.

Service configuration

The default Lambda runtime has changed from NodeJS 12 to NodeJS 14, given this is now the default runtime recommended by AWS.

Additionally, the nodejs10.x, python2.7, ruby2.5 and dotnetcore2.1 runtimes are no longer supported and accepted by AWS Lambda. As such, these runtimes will no longer be accepted in v3.

In serverless.yml, the service key no longer accepts a YAML object (learn more).

# Deprecated in v2, removed in v3:
    name: my-service

# Correct syntax:
service: my-service

All options that used to be defined inside the service key have been moved to other sections (mentioned below in that document). This change clears up confusion that existed between the service and provider sections.

API Gateway

When configuring API Gateway, some configuration options have moved to a dedicated sub-section of provider. That will help clear up confusion with similar httpApi settings.

  # Deprecated in v2, removed in v3:
  apiKeys: ...
  resourcePolicy: ...
  usagePlan: ...

  # Correct syntax:
    apiKeys: ...
    resourcePolicy: ...
    usagePlan: ...

The schema option on HTTP events has also been renamed to schemas. That change allowed us to support much more schema validation features:

    handler: hello.handler
      - http:
            # Deprecated in v2, removed in v3:
            schema: ...
            # Correct syntax:
            schemas: ...

Learn more about schema changes.

When an external API Gateway is used and imported via provider.apiGateway.restApiId, both provider.logs.restApi and provider.tracing.apiGateway options are ignored. In v3, an error will be thrown if these options are defined. Indeed, these settings are applicable only if the API Gateway is provisioned by Serverless Framework.

The CloudFormation tags defined in provider.tags will now be correctly applied to HTTP APIs stages (learn more).

Starting with v3, AWS's recommended behavior for API Gateway authorizers will become the default: functions[].events[].http.authorizer.identitySource will no longer be set to method.request.header.Authorization by default when caching is disabled (i.e. for authorizers of type "request" with resultTtlInSeconds set to "0") (learn more).


Some CloudFront behavior options where deprecated by AWS: ForwardedValues, MinTTL, MaxTTL and DefaultTTL. These options have been removed. Use the new "cache policy" feature instead (learn more).


By default, all EventBridge resources (including Lambda triggers) will now be deployed using native CloudFormation resources, instead of a custom resource (learn more). The change has the benefit of relying on native AWS features now, which will be more stable and future-proof.

Since this is a hard breaking change for Serverless Framework v2 users, it is possible to keep the legacy behavior (based on custom resources) by using this flag:

    useCloudFormation: false

With this flag, v2 users can upgrade to v3 without breaking change. Note that useCloudFormation: false will be deprecated eventually, and will not be supported in the future.


When configuring KMS keys, some configuration options have moved (learn more):

# Deprecated in v2, removed in v3:
  awsKmsKeyArn: ...
    awsKmsKeyArn: ...

# Correct syntax:
  kmsKeyArn: ...
    kmsKeyArn: ...

That allowed us to make the KMS configuration consistent with all other AWS resources: these are now configured in the provider section.

Alexa skill

alexaSkill events now require an appId (learn more). That change was required to implement a more stable deployment, as well as to deploy more restricted IAM permissions.

Lambda Hashing Algorithm

By default, Lambda version hashes will now be generated using a more robust algorithm (fixes determinism issues). Since this change requires manual effort during the migration, you can keep using the old algorithm in v3 via the following configuration:

  lambdaHashingVersion: 20200924

Adding the above configuration is sufficient to be compatible with v3.

However, we highly encourage upgrading to the new algorithm. To upgrade, you must:

  1. Enable the new hashing mechanism in v2 by setting:

      lambdaHashingVersion: 20201221
  2. Redeploy with code or configuration changes in all functions.

    If your deployment doesn't contain changes, you will get the following error: "A version for this Lambda function exists."

    To force changes in all functions, you can deploy code changes, upgrade dependencies, or even temporarily create empty files in your codebase.

    Alternatively, you can use the --enforce-hash-update helper:

    1. Run serverless deploy with the --enforce-hash-update flag: that flag will force changes by temporarily overriding the Lambda function descriptions (there is no runtime impact).
    2. Run serverless deploy without the flag above to restore the descriptions on all Lambda functions.

Remember that you will need to deploy with changes to each stage you have previously deployed. For development stages another option is to remove and recreate the stage entirely.

New variable resolver engine

A more robust and powerful variable resolver engine was introduced behind a flag in Serverless Framework v2. This new engine is used by default in v3.

It supports the same variables with the same syntax. The main impacts are:

  • Some edge cases (ambiguous configuration) now throw errors
  • A very small share of unmaintained plugins haven't been updated to support the new engine

You can prepare the upgrade from v2 to v3 by enabling the new engine:

# serverless.yml
service: myapp
variablesResolutionMode: 20210326

In v3, the variablesResolutionMode option can be removed as the new engine becomes the default.

Low-level changes

Internal changes that may impact plugins or advanced use cases:

  • Plugins can no longer define custom variables via the legacy variable resolver (learn more).

    The new variable resolver API was introduced to provide a simpler and more stable way of defining custom variables. Most plugins have switched to that new variable resolver, but older plugins may still require some updates.

  • CloudFormation outputs are now always exported (learn more

    This change allows us to simplify and clean up the internals by removing options and logic switches. The use cases for not exporting CloudFormation outputs were very uncommon.

  • When using the Serverless Framework programmatically, the service configuration must be at the root directory of the service (learn more) and the arguments have changed (learn more here as well as here).

    Using the Serverless Framework programmatically is a very unusual and low-level scenario: we took advantage of the major version to improve the API.

Deprecated features that will be kept in v3

Some Serverless Framework v2 features were marked as deprecated. However, given they are still widely used, we have chosen to keep the following features in v3.

IAM configuration has changed, yet both syntaxes are supported in v3:

# Older syntax, still supported in v3
  role: ...
  rolePermissionsBoundary: ...
  iamRoleStatements: ...
  iamManagedPolicies: ...
  cfnRole: ...

# New syntax
      name: ...
      permissionsBoundary: ...
      statements: ...
      managedPolicies: ...
    deploymentRole: ...

In the same spirit, packaging configuration has changed but both syntaxes are supported in v3:

# Older syntax, still supported in v3
    - 'src/**'
    - src/function/handler.js

# New syntax
    - '!src/**'
    - src/function/handler.js

Configuration validation is still kept at the "warning" level by default (instead of turning to errors, as initially planned). To turn validation issues into errors, use:

# v2 and v3 both keep the same default behavior: warnings by default
configValidationMode: warn

# Opt-in errors via:
configValidationMode: error

Unlike planned initially, loading .env files is kept opt-in via useDotenv: true.

Additionally, the short form serverless deploy -f <function> is still allowed in v3, but serverless deploy function -f <function> stays the preferred form.


The serverless-dotenv-plugin is directly impacted by v3. Indeed, for technical reasons the plugin will no longer be able to resolve ${env:xxx} variables from .env files.

However, .env files are now natively supported by Serverless Framework v3. Set useDotenv: true to use .env variables with ${env:xxx}:

useDotenv: true

    FOO: ${env:FOO}

The plugin can still be used as usual if you want to automatically import all variables from .env into functions.

  - serverless-dotenv-plugin

    # With the plugin enabled, all variables in .env are automatically imported
Go to Github