gatsbyjs/gatsby · critical

invalid bucket ${process.env.S3_BUCKET}

Error message

invalid bucket ${process.env.S3_BUCKET}

What it means

Thrown inside the S3Screenshot constructor in the gatsby-transformer-screenshot Lambda. The constructor calls s3GetBucketLocation(S3_BUCKET) to resolve the AWS region for building the public file URL. If that call resolves to a falsy value (null), the bucket name is invalid, inaccessible, or the AWS credentials lack permission to inspect it.

Source

Thrown at packages/gatsby-transformer-screenshot/lambda/screenshot.js:61

  }

  async putFile(fileBuffer) {
    await fsPromises.writeFile(this.fileUrl, fileBuffer)
    this.expires = undefined
    return { url: this.fileUrl, expires: this.expires }
  }
}

/**
 * put / get a screenshot to S3
 */
class S3Screenshot extends Screenshot {
  constructor(opts) {
    super(opts)
    // async jiggery pokery
    return (async () => {
      const region = await s3GetBucketLocation(process.env.S3_BUCKET)
      if (!region) throw new Error(`invalid bucket ${process.env.S3_BUCKET}`)
      this.fileUrl = `https://s3-${region}.amazonaws.com/${process.env.S3_BUCKET}/${this.key}`
      return this // when done
    })()
  }

  async getFile() {
    const meta = await s3HeadObject(this.key)
    if (meta && meta.Expiration) {
      this.expires = getDateFromExpiration(meta.Expiration)
      const now = new Date()
      if (now < this.expires) {
        return { url: this.fileUrl, expires: this.expires }
      }
    }
    return false
  }

  async putFile(fileBuffer) {

View on GitHub (pinned to 8b06340921)

Solutions

  1. Verify the S3_BUCKET env var matches an existing bucket: run `aws s3 ls s3://BUCKET_NAME` with the same credentials the Lambda uses.
  2. Ensure the Lambda execution role has s3:GetBucketLocation and s3:PutObject permissions on the target bucket.
  3. Confirm AWS_REGION/AWS_DEFAULT_REGION is set correctly for the bucket's region.
  4. Check that AWS credentials (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY) are valid and not expired.

Example fix

// before
S3_BUCKET=my-typo-bucket

// after — verify bucket exists and IAM permits access
aws s3 ls s3://my-correct-bucket
# set env: S3_BUCKET=my-correct-bucket
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight check before Lambda handles a request
const AWS = require('aws-sdk')

async function validateS3Bucket(bucketName) {
  const s3 = new AWS.S3()
  try {
    const data = await s3.getBucketLocation({ Bucket: bucketName }).promise()
    if (!data.LocationConstraint && data.LocationConstraint !== '') return false
    return true
  } catch {
    return false
  }
}

// At cold start:
if (!await validateS3Bucket(process.env.S3_BUCKET)) {
  console.error('S3_BUCKET is invalid or inaccessible')
}

Try / catch

// Wrap the S3Screenshot constructor usage
try {
  const screenshot = await new S3Screenshot(opts)
  // use screenshot...
} catch (e) {
  if (e.message.includes('invalid bucket')) {
    // fall back to local FS or report configuration error
    console.error('S3 bucket misconfigured:', e.message)
  } else {
    throw e
  }
}

Prevention

When it happens

Trigger: The Lambda starts, reads process.env.S3_BUCKET, calls s3.getBucketLocation via the AWS SDK, and the promise resolves null — either because the SDK returned an error (which s3GetBucketLocation swallows by resolving null) or the bucket does not exist in the configured region. The constructor then rejects with this error.

Common situations: S3_BUCKET env var is misspelled, points to a bucket in a different AWS account, the Lambda's IAM role lacks s3:GetBucketLocation permission, the bucket was deleted, or AWS credentials are not configured (defaulting to a region where the bucket doesn't exist).

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/0793865a0f8da53c. Report an issue: GitHub.