Amazon S3异常: “指定的密钥不存在”

我在一个 Android 应用程序中使用 AmazonS3Client,使用 getObject 请求从我的 AmazonS3桶中下载图像。

目前,我得到了一个例外:

com.amazonaws.services.s3.model.AmazonS3Exception:
The specified key does not exist.
(Service: Amazon S3; Status Code: 404; Error Code: NoSuchKey;

即使我能够在我的 S3桶中看到具有指定键的对象。

287066 次浏览

这个错误其实很简单。它只是意味着您的文件不存在于 S3 bucket 中。有几点可能是错误的:

  1. 您可能试图引用错误的文件。请仔细检查您试图检索的路径。

  2. 无论何时上传文件,它一定是失败了。检查 S3Sync 进程的日志,看看是否可以找到任何相关输出

来源

对我来说,这个对象肯定存在并且被正确地上传了,然而,它的 s3url 仍然出现了同样的错误:

<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>

我发现原因是我的文件名包含一个 #字符,这可能需要特殊处理 根据文件记录

删除这个字符并生成新的 s3url 解决了我的问题。

在我的例子中,出现错误是因为我已经将包含网站文件的整个文件夹上传到容器中。

我把所有文件都移出了文件夹,直接放进了集装箱。

出现问题的原因是错误的或在 Bucket/Key 名称中输入错误。请检查您提供的 bucket 或密钥名是否存在。

请注意,即使由于 s3的 最终内存一致性模型,文件路径是正确的,这种情况也可能发生。基本上,在写入对象之后,读取对象可能会有一些延迟。有关更多信息,请参见 这份文件

别忘了桶是特定区域的,这可能是个问题。

还可以尝试使用 S3控制台导航到实际的对象,然后单击 Copy Path,您将得到如下内容:

s3://<bucket-name>/<path>/object.txt

只要你把它正确地传递给解析器,我发现这是最安全的做法。

步骤1: 获取最新的 aws-java-sdk

<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-aws -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.660</version>
</dependency>

步骤2: 正确的导入

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ObjectListing;

如果确定 bucket 存在,则 Specified key does not exists error将意味着桶名不是正确的 下咒了(包含斜杠或特殊字符)。有关变数命名原则,请参阅 ABc2。

该文件引述如下:

如果桶中的请求对象可用,并且用户仍然 从 Amazon S3获取404 NoSuchKey 错误,请检查以下内容:

确认请求与对象名称完全匹配,包括 对象名称的大写 例如,如果一个对象名为 myimage.jpg,但是 Jpg 被请求,然后请求者收到一个404 NoSuchKey 确认请求的路径与对象的路径匹配。 例如,如果对象的路径为 Awsexamplebucket/Downloads/February/Images/image. jpg,但是 请求的路径是 awsexamplebucket/Downloads/February/image. jpg,然后 请求者收到一个404NoSuchKey 错误 对象包含任何空格,请确保请求使用了正确的 语法来识别路径 要将对象下载到 Windows 计算机,必须使用引号 对象路径周围的标记,类似于: aws s3 cp “ s3://awsexamplebucket/Backup Copy Job 4/3T000000. vbk”, 中启用服务器访问日志记录来查看请求记录 进一步详细说明可能导致404错误的问题。

AWSCredentials credentials = new BasicAWSCredentials(AWS_ACCESS_KEY_ID, AWS_SECRET_KEY);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withRegion(Regions.US_EAST_1).build();
ObjectListing objects = s3Client.listObjects("bigdataanalytics");
System.out.println(objects.getObjectSummaries());

在我的例子中,这是因为文件名包含空格。多亏了这个 文件(与问题无关) ,我们解决了这个问题:

from urllib.parse import unquote_plus
key_name = unquote_plus(event['Records'][0]['s3']['object']['key'])

您还需要将 urllib 上传为一个包含相应版本的层(如果您的 lambda 是 Python 3.7,则必须在 Python 3.7环境中打包 urllib)。

原因是 AWS 将’’转换为’+’(为什么...) ,这是非常有问题的..。

我也遇到了这个问题,但是在我的例子中,我在构造目标键时无意中改变了源对象键的内部状态:

  source_objects.each do |item|
key = item.key.sub!(source_prefix, dest_prefix)
item.copy_to(bucket: dest_bucket, key: key)
end

我对 Ruby 还是个新手,没有注意到 sub!有副作用,而 sub应该被用来代替。

我在 NodeJS Lambda 函数中遇到了这个问题,该函数是由上传到 S3的文件触发的。

我的错误在于没有解码包含冒号的对象密钥:

let key = decodeURIComponent(event.Records[0].s3.object.key);

在我的情况下,我有错误的密钥名称。请确保您有正确的密钥名称。 enter image description here

如果文件位于 bucket 中的子文件夹中,则该子文件夹应该是键的一部分,而不是 bucket 的一部分。使用以下命令,我能够读取 PowerShell 中的文件。

例如:

Get-S3Object -BucketName "$Bucket" -Key "$subFolder/$fileName"

我有同样的问题,我试图从 S3读取的文件不在那里。我会检查文件路径是否正确,您正在寻找的文件是存在的。

我只是提供了一个错误:

404 Not Found
Code: NoSuchKey
Message: The specified key does not exist.
Key: index.html
RequestId: 3C8J01Y73CKKJSCQ
HostId: QiQ6bqe3Cff/XjDDGm10IAArp9j6kajGKFIv4/JiJBfOFjLLxsiE796TuoLviPsCQl3KOma+Ma0=

这背后的原因是我选择了访问点 index.html,但是,我没有拖动文件上传,而是选择了整个文件夹。

因此,index.html文件确实位于 configuring-s3-code/index.html位置,而不是直接位于根文件夹中。

所以,请仔细检查代码库的访问点,问题可能就在那里。

在我的例子中,它就像使用错误的斜杠一样简单(错误: 像“ foo bar.txt”这样的微软风格。正确: 像“ foo/bar.txt”这样的 Unix 风格) 如果您使用类似 Path 的辅助函数,那么很容易发生这种情况。

我在一些国家出现了这个错误,但不是全部(通过使用我的 VPN 选择不同的国家进行测试)。

对我来说,解决这个问题的方法是在 CloudFront 中创建一个“自定义错误响应”。

我使用 200的响应代码将 404错误代码重定向到 /index.html

然后,我创建了一个无效,一切又开始工作。

在我的情况下,文件的链接是错误的-位置错过。您可以通过从 AWS 后端复制一个来检查正确的链接。 enter image description here

有这个问题的人可能还想检查这个 叠线

转到 bucket 设置,并将错误文档更改为与索引文档相同的内容,可能会奏效: < br > < br > 例如: enter image description here

对我来说更奇怪: 在我的角度应用程序,托管在 S3下的 CF 来源路径/prod/v1.2,我指向一个网址像: 我的 example.com/token/sdkjnasdalkjsd.asdasdasd.asdad 有一段时间了

在这种情况下,出于某些原因,Cloudfront 似乎没有添加 Origin 路径,而是试图将其解析为一个文件(因为 toke 有句号?)以404结尾

为了解决这个问题,我不得不改变404的方向