serverless/serverless · error · ServerlessError

AWS_ECR_LOGIN_FAILED

AWS_ECR_LOGIN_FAILED

Error message

Failed to get authorization data from ECR

What it means

Thrown by ECR.loginToEcrRepository (ecr.js:95) when GetAuthorizationTokenCommand resolves successfully but authorizationData or authorizationData[0].authorizationToken is absent. The AWS contract guarantees a populated authorizationData array for valid accounts, so reaching this throw usually means ECR is not enabled or the response shape is unexpected. Note: the subsequent docker login execAsync (ecr.js:108) is NOT in this error path — a docker failure surfaces as a raw child_process error instead.

Source

Thrown at packages/engine/src/lib/aws/ecr.js:95

      throw new ServerlessError(error.message, 'AWS_ECR_REPOSITORY_NOT_FOUND')
    }
  }

  /**
   * Login to AWS ECR repository using Docker
   * @param {Object} params - Login parameters
   * @param {string} params.ecrRepository - The ECR repository URI to login to
   * @returns {Promise<void>}
   */
  async loginToEcrRepository({ ecrRepository }) {
    const authResponse = await this.client.send(
      new GetAuthorizationTokenCommand({}),
    )
    if (
      !authResponse.authorizationData ||
      !authResponse.authorizationData[0].authorizationToken
    ) {
      throw new ServerlessError(
        'Failed to get authorization data from ECR',
        'AWS_ECR_LOGIN_FAILED',
      )
    }

    const authToken = authResponse.authorizationData[0].authorizationToken
    const [username, password] = Buffer.from(authToken, 'base64')
      .toString()
      .split(':')

    // Docker login to ECR
    const loginCommand = `echo ${password} | docker login --username ${username} --password-stdin ${ecrRepository}`
    await execAsync(loginCommand)

    logger.debug('Successfully logged into AWS ECR repository')
  }

  /**

View on GitHub (pinned to b9d7ea51c8)

Solutions

  1. Confirm ecr:GetAuthorizationToken is allowed and run aws ecr get-login-password --region <region> manually to verify the registry responds.
  2. Ensure the AWS account has been initialised for ECR in the target region (pushing any image once enables it).
  3. Align @aws-sdk/client-ecr version across the engine.
  4. Verify docker is installed and reachable, since the later execAsync is a separate failure surface.

Example fix

// before
if (!authResponse.authorizationData || !authResponse.authorizationData[0].authorizationToken) {
  throw new ServerlessError('Failed to get authorization data from ECR', 'AWS_ECR_LOGIN_FAILED')
}

// after — surface why it was empty
const data = authResponse.authorizationData?.[0]
if (!data?.authorizationToken) {
  throw new ServerlessError(
    `ECR returned no authorization token (region=${region}, data=${JSON.stringify(authResponse).slice(0, 200)})`,
    'AWS_ECR_LOGIN_FAILED',
  )
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the deploy role can fetch an auth token before calling loginToEcrRepository
// Required permission: ecr:GetAuthorizationToken on '*'
// And confirm docker is installed: which docker

Type guard

function hasAuthorizationToken(res) {
  return Boolean(
    res && Array.isArray(res.authorizationData) &&
    res.authorizationData[0] && typeof res.authorizationData[0].authorizationToken === 'string'
  )
}

Try / catch

try {
  await ecr.loginToEcrRepository({ ecrRepository })
} catch (e) {
  if (e.code === 'AWS_ECR_LOGIN_FAILED') {
    throw new Error(`ECR auth token unavailable in region ${region}; ensure ECR is enabled and ecr:GetAuthorizationToken is allowed`)
  }
  throw e
}

Prevention

When it happens

Trigger: GetAuthorizationToken returns with authorizationData === undefined or an empty array; authorizationData[0].authorizationToken missing. Happens when the account has no ECR registry in the region, the caller lacks ecr:GetAuthorizationToken (usually throws instead), or an SDK/proxy mangled the response.

Common situations: Brand-new AWS account where ECR has never been initialised in the region; a region that does not offer ECR; an outdated @aws-sdk/client-ecr returning a different shape; corporate MITM proxy stripping response fields. Security note: the password is interpolated into a shell command string (line 107) — generally safe for AWS tokens but visible in process listings.

Related errors


AI-assisted analysis of serverless/serverless@b9d7ea51c8 (2026-08-13). Data as JSON: /api/errors/ab2c4d1c333c157b. Report an issue: GitHub.