AWS
S3
botocore
Python
error handling

botocore.exceptions.ClientError An error occurred 404 when calling the HeadObject operation Not Found

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

botocore.exceptions.ClientError: An error occurred (404) when calling the HeadObject operation: Not Found indicates S3 could not find the object at the exact bucket + key you requested, or your access pattern obscures existence. HeadObject is commonly used for existence checks before download, copy, or metadata reads, so this error appears often in automation scripts.

The fix is usually not retry-only. You need to verify key path construction, bucket region, permissions, and object state (including versioning and delete markers).

Core Sections

1) Understand what HeadObject validates

HeadObject checks metadata for one exact key. Any mismatch in case, prefix, encoding, or path separators returns 404.

python
1import boto3
2from botocore.exceptions import ClientError
3
4s3 = boto3.client("s3")
5
6try:
7    s3.head_object(Bucket="my-bucket", Key="reports/2026-03-01.csv")
8    print("Object exists")
9except ClientError as e:
10    print(e.response["Error"]["Code"])

2) Validate bucket, key, and region first

Many incidents are simple environment mismatch.

python
1session = boto3.Session(region_name="us-east-1")
2s3 = session.client("s3")
3
4bucket = "my-bucket-prod"
5key = "input/data.json"

Confirm the same values in CLI:

bash
aws s3api head-object --bucket my-bucket-prod --key input/data.json --region us-east-1

3) Check permissions and policy behavior

Insufficient permissions can present as missing object behavior depending on policy setup. Ensure principal has at least s3:GetObject on the target key path and s3:ListBucket where needed for diagnostics.

Also confirm cross-account role assumption and session credentials are what you expect at runtime.

4) Versioning and delete-marker edge cases

With versioned buckets, a current delete marker makes object appear absent for default reads.

bash
aws s3api list-object-versions --bucket my-bucket --prefix input/data.json

If delete marker exists, either restore previous version or address lifecycle/deletion pipeline.

5) Key construction bugs in application code

Typical bugs:

  • accidental double slashes,
  • URL-decoding mismatch,
  • trailing spaces or newline chars,
  • wrong date formatting in key prefix.

Add logging with repr(key) for exact visibility.

python
print(f"DEBUG key={key!r}")

6) Resilient handling pattern

For workflows where missing object is expected, handle 404 as business logic rather than generic failure.

python
1def object_exists(s3, bucket, key):
2    try:
3        s3.head_object(Bucket=bucket, Key=key)
4        return True
5    except ClientError as e:
6        if e.response["Error"]["Code"] in ("404", "NoSuchKey", "NotFound"):
7            return False
8        raise

Reserve retries for transient network or throttling errors, not persistent key mismatch.

7) Production checklist for S3 HeadObject troubleshooting

Treat this topic as an operational concern, not only a coding snippet. Start by defining one explicit success metric that reflects business behavior, such as failed request rate, pipeline lag, model quality drift, or user-visible latency. Then create a small acceptance checklist that can run in both staging and production-like test environments. The checklist should verify the happy path, at least one failure path, and one boundary case.

Capture configuration assumptions close to the implementation, including timeouts, versions, environment variables, and external dependencies. If behavior varies by environment, encode those differences in configuration rather than hardcoded branches. Add lightweight observability from day one: key counters, error categorization, and structured logs with identifiers that support correlation during incident response.

Finally, define rollback and ownership before rollout. Decide who responds to alerts, what threshold should trigger rollback, and which fallback mode keeps the system functional if this component degrades. A clear ownership and rollback plan turns isolated technical knowledge into a maintainable production practice.

Common Pitfalls

  • Retrying 404 errors indefinitely without validating bucket/key construction.
  • Assuming path separators or key case are normalized automatically by S3.
  • Debugging with one AWS profile while the app runs with another credential source.
  • Ignoring versioned bucket delete-marker behavior.
  • Treating permission-denied scenarios as guaranteed nonexistence.

Summary

A 404 on HeadObject usually means the requested key is not resolvable in the target bucket context. Resolve it by validating exact key strings, region/account alignment, permissions, and versioning state. Implement explicit 404 handling in code and reserve retries for truly transient failures.


Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design