AWSRunbook 0/4 done
NoSuchKey

AWS Error NoSuchKey: S3 NoSuchKey

Warning✕ Not retryable · fix the payloadHTTP 404 Not FoundAPI Gateway
TL;DR · 10-second read

No object exists at that exact key in the bucket. Check for a leading slash, URL-encoded characters and case, and handle NoSuchKey as a 404 in code.

Identify: does your log match?

What you see · exact log / response
NoSuchKey: The specified key does not exist.
    at de_NoSuchKeyRes (/app/node_modules/@aws-sdk/client-s3/dist-cjs/index.js:4908:21)
  '$fault': 'client',
  '$metadata': { httpStatusCode: 404, requestId: 'R7X1N9M2Q4K8P0ZT', attempts: 1 },
  Code: 'NoSuchKey',
  Key: 'uploads/2026/10/report final.pdf'
  1. High

    Key built with wrong encoding

    Passing a URL-encoded key (report%20final.pdf) or a + for spaces to the SDK, which encodes again. S3 keys are literal strings.

  2. Medium

    Leading slash or wrong prefix

    /uploads/a.png and uploads/a.png are different keys. Path joins often add the slash.

  3. Low

    Read before write completes

    Reading right after an async upload that has not finished, or from the wrong region/bucket.

Fix

Catch NoSuchKey and return 404

✕ Broken · TypeScript
const obj = await s3.send(new GetObjectCommand({ Bucket, Key }));
return new Response(obj.Body as ReadableStream);
✓ Fixed · TypeScript
import { GetObjectCommand, NoSuchKey } from '@aws-sdk/client-s3';

try {
  const obj = await s3.send(new GetObjectCommand({ Bucket, Key }));
  return new Response(obj.Body!.transformToWebStream());
} catch (err) {
  if (err instanceof NoSuchKey) return new Response('Not found', { status: 404 });
  throw err;
}

SDK v3 exports NoSuchKey as a typed exception class, so instanceof is reliable.

Verify: reproduce it on purpose

Reproduce locally · aws
$ aws s3api get-object --bucket "$BUCKET" --key does/not/exist.txt /tmp/x

Run it against a dev environment to trigger NoSuchKey on purpose and test your error handler.

Prevent

  • Store the exact key returned at upload time.
  • Use HeadObject to check existence cheaply.
  • Grant s3:ListBucket so missing keys return 404, not 403.

FAQ

Why do I get AccessDenied instead of NoSuchKey?

The caller lacks s3:ListBucket on the bucket, so S3 hides the difference. Add ListBucket to get 404s.

Is S3 eventually consistent for new objects?

No, since December 2020 S3 provides strong read-after-write consistency for all PUTs and DELETEs.

How do I list keys under a prefix?

aws s3api list-objects-v2 --bucket my-bucket --prefix uploads/2026/ --max-items 20.

Related errors

Last verified 2026-10-18 · Source: botocore service models (errors per operation) · Official docs ↗ · ~12,100 searches/mo