I have code which lists keys using ListObjectsPages
->Contents
->Key
and copies those keys using CopyObject
. This works in general but for some keys it's complaining NoSuchKey: The specified key does not exist.
The set of keys it's complaining about include keys with +
.
ListObjectsPages
returns key "foo+bar".CopyObject
on "foo+bar" gives the NoSuchKey
error.CopyObject
on "foo bar" (unescaped) gives the NoSuchKey
error.Oddly, if I use the CLI: aws s3 cp
on "foo+bar", the copy works. But I can't use the CLI. I need to use the sdk.
I'm using v1.8.11
As Rayfen mentioned, the plus characters could be the result of space replacement.
Update: Everything was hashed out here https://github.com/aws/aws-sdk-go/issues/1438. Rayfen was right about needing to QueryEscape
. I'm going to award the only current answer with the bounty since it adds useful information, but not select it as correct.
This details what was happening: https://github.com/aws/aws-sdk-go/issues/1438
CopySource
needs to be url-encoded and not the Key
field, which was surprising to me. (I was url-encoding both.)path.Join
which strips out trailing \
. This is a problem because s3 keys can have trailing \
- which represents a sort of folder.The object key and metadata document is clear:
The following character sets are generally safe for use in key names:
- Alphanumeric characters
[0-9a-zA-Z]
- Special characters
!
,-
,_
,.
,*
,'
,(
, and)
Not only + would be converted into space with, but, from the section "Characters That Might Require Special Handling" of the same page, ':
' should also be converted back from space, which QueryUnescape
does not do (it only convert space back to +
).
Check if your keys include other special characters to be handled with care, like :
(also replaced by space), @
or =
(replaced by ;
), or ,
and ?
.
Check in particular if the key obtained from QueryUnescape
has a + instead of a ':
' in the original key: that could be a space incorrectly "unescaped".