Problem
In main.go, S3 object keys are extracted directly from S3 event notifications and passed to GetObject:
key := record.S3.Object.Key
...
getObjectOutput, err := s3Client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
According to the official AWS S3 Event Notification specification:
The key value in an Amazon S3 event notification is URL-encoded. You must URL-decode the key before using it in Amazon S3 API calls.
For example:
- Spaces in keys are encoded as
+ or %20
- Characters like
=, :, @, & are percent-encoded (common in partitioned S3 paths, e.g. year=2026/date=2026-09-29/)
Because the key is not unescaped, S3 returns a NoSuchKey 404 error when fetching objects with any encoded characters.
Proposed Solution
Decode the object key using Go's net/url package before calling S3 APIs:
decodedKey, err := url.QueryUnescape(key)
if err != nil {
return fmt.Errorf("failed to decode S3 object key %q: %w", key, err)
}
Note that S3 encodes spaces as +, which url.QueryUnescape handles properly.
Acceptance Criteria
Problem
In main.go, S3 object keys are extracted directly from S3 event notifications and passed to
GetObject:According to the official AWS S3 Event Notification specification:
For example:
+or%20=,:,@,&are percent-encoded (common in partitioned S3 paths, e.g.year=2026/date=2026-09-29/)Because the key is not unescaped, S3 returns a
NoSuchKey404 error when fetching objects with any encoded characters.Proposed Solution
Decode the object key using Go's
net/urlpackage before calling S3 APIs:Note that S3 encodes spaces as
+, whichurl.QueryUnescapehandles properly.Acceptance Criteria
+,%20,=, etc.) are properly decoded before callings3Client.GetObject+, and special characters