You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地Spark Streaming连接S3报Forbidden错误求助

解决Spark Streaming读取S3时的Forbidden错误

我之前本地跑Spark Streaming读S3也踩过这个Forbidden的坑,终端明明能正常访问S3,偏偏Spark就报错,给你几个实际排查的方向,亲测有用:

1. 先确认Spark真的拿到了你的环境变量

终端里设置的环境变量不一定能被Spark进程继承,特别是用IDE启动或者后台运行的时候。你可以在代码里加几行打印,看看Spark能不能读到这些变量:

// Scala示例,Java/Python写法类似
println("AWS_ACCESS_KEY_ID: " + System.getenv("AWS_ACCESS_KEY_ID"))
println("AWS_SECRET_ACCESS_KEY: " + System.getenv("AWS_SECRET_ACCESS_KEY"))
println("AWS_SESSION_TOKEN: " + System.getenv("AWS_SESSION_TOKEN"))

要是输出是空的,说明Spark没拿到变量,启动的时候得把变量直接挂在spark-submit命令前面:

AWS_ACCESS_KEY_ID=你的密钥ID AWS_SECRET_ACCESS_KEY=你的密钥 AWS_SESSION_TOKEN=你的会话令牌 spark-submit --class 你的主类路径 你的应用jar包

2. 必须保证Hadoop-AWS版本和Spark兼容

这个是最容易踩的坑!Spark依赖的Hadoop版本和你用的hadoop-aws jar版本必须严格匹配,比如Spark 3.x一般对应Hadoop 3.x,版本不兼容的话认证逻辑直接乱掉。你可以在spark-submit里指定正确的jar包,比如Spark 3.3.0搭配Hadoop 3.3.4:

spark-submit --jars https://repo1.maven.org/maven2/org/apache/hadoop/hadoop-aws/3.3.4/hadoop-aws-3.3.4.jar,https://repo1.maven.org/maven2/com/amazonaws/aws-java-sdk-bundle/1.12.262/aws-java-sdk-bundle-1.12.262.jar --class 你的主类路径 你的应用jar包

或者在Maven/Gradle的依赖里同步版本,别让依赖冲突。

3. 直接把认证参数硬怼到SparkConf里

有时候环境变量的方式就是不生效,那不如直接在代码里把参数配置到SparkConf,跳过环境变量的依赖:

val sparkConf = new SparkConf()
  .setAppName("S3StreamingDemo")
  .setMaster("local[*]")
  .set("spark.hadoop.fs.s3a.access.key", System.getenv("AWS_ACCESS_KEY_ID"))
  .set("spark.hadoop.fs.s3a.secret.key", System.getenv("AWS_SECRET_ACCESS_KEY"))
  .set("spark.hadoop.fs.s3a.session.token", System.getenv("AWS_SESSION_TOKEN"))
  .set("spark.hadoop.fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")

注意用s3a协议,这是Hadoop官方推荐的最新S3实现,旧的s3/s3n别用了。

4. 检查S3桶的权限和IAM身份

终端能访问不代表Spark用的身份有足够权限!要确保你的AWS凭证对应的IAM用户/角色有这两个关键权限:

  • s3:ListBucket:Spark Streaming需要扫描桶里的文件,必须有这个权限
  • s3:GetObject:读取文件内容的权限
    去IAM控制台看看该用户的权限策略,或者用终端命令再测一遍:
aws s3 ls s3://你的桶名
aws s3 cp s3://你的桶名/某个测试文件 .

要是终端能正常执行,那大概率是Spark这边的配置问题;要是终端也报错,那就是权限没给够。

5. 临时会话令牌别过期了

如果你用的是临时凭证(AWS_SESSION_TOKEN),得确认它有没有过期,或者权限范围对不对。可以用这个命令验证:

aws sts get-caller-identity

要是返回错误,说明凭证失效了,得重新获取新的临时凭证。

小技巧:本地开发的话,把凭证写到~/.aws/credentials文件里更省心,Hadoop-AWS会自动读这个文件的配置,不用每次设环境变量:

[default]
aws_access_key_id = 你的密钥ID
aws_secret_access_key = 你的密钥
aws_session_token = 你的会话令牌

内容的提问来源于stack exchange,提问作者covfefe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:04:23