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

使用AWS JavaScript SDK v2可列出S3 Bucket但无法上传文件求助

AWS SDK v2 上传S3 CredentialsError 问题解决

问题背景

项目依赖限制必须使用AWS JavaScript SDK v2,执行上传文件到S3 Bucket的代码时触发凭证错误,但VSCode终端的AWS CLI可正常完成上传,且代码已配置profile并能正常列出Bucket。

上传代码

const fs = require('fs');
const AWS = require('aws-sdk');

let s3 = new AWS.S3({apiVersion: '2006-03-01'});

const fileName = '/Users/*****/****/*****-ui/**/***/****/BE-Commands/cmd.json';

const uploadFile = () => {
  fs.readFile(fileName, (err, data) => {
     if (err) throw err;
     const params = {
         Bucket: 'bucket-test', // 替换为你的Bucket名称
         Key: 'contacts.csv', // 文件将保存为 bucket-test/contacts.csv
         Body: JSON.stringify(data, null, 2)
     };
     s3.upload(params, function(s3Err, data) {
         if (s3Err) throw s3Err
         console.log(`文件上传成功:${data.Location}`)
     });
  });
};

uploadFile();

报错信息

Error: connect EHOSTDOWN 169.254.169.254:80 - Local (***.1***.1.182:*****)
    at internalConnect (node:net:1084:16)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:465:18)
    at node:net:1290:9
    at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
  message: 'Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1',
  errno: -64,
  code: 'CredentialsError',
  syscall: 'connect',
  address: '1****.254.169.254',
  port: 80,
  time: 2023-08-10T18:15:50.727Z,
  originalError: {
    message: 'Could not load credentials from any providers',
    errno: -64,
    code: 'CredentialsError',
    syscall: 'connect',
    address: '**********',
    port: 80,
    time: 2023-08-10T18:15:50.722Z,
    originalError: {
      message: 'EC2 Metadata roleName request returned error',
      errno: -64,
      code: 'EHOSTDOWN',
      syscall: 'connect',
      address: '***.254.***.***',
      port: 80,
      time: 2023-08-10T18:15:50.722Z,
      originalError: {
        errno: -64,
        code: 'EHOSTDOWN',
        syscall: 'connect',
        address: '***.***.***.***',
        port: 80,
        message: 'connect EHOSTDOWN 169.254.169.254:80 - Local (***.***.1.***:49426)'
      }
    }
  }
}

问题原因

报错中的169.254.169.254是EC2实例元数据服务地址,SDK v2在找不到本地凭证时会自动尝试请求该地址获取IAM角色凭证,但本地开发环境无法访问这个地址,因此触发EHOSTDOWN错误。同时SDK v2默认不会加载~/.aws/config中的profile配置,即便你已经配置了profile,也需要显式指定或通过环境变量开启加载。

修复方案

1. 显式指定profile初始化S3客户端

修改S3实例的初始化代码,直接指定要使用的profile名称:

const AWS = require('aws-sdk');

// 替换为你的AWS配置文件中的profile名称
let s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  credentials: new AWS.SharedIniFileCredentials({ profile: '你的profile名' })
});

2. 通过环境变量开启配置加载

在运行代码前设置环境变量AWS_SDK_LOAD_CONFIG=1,让SDK自动加载~/.aws/config中的配置:

  • Linux/macOS终端:
    export AWS_SDK_LOAD_CONFIG=1
    node 你的脚本文件名.js
    
  • Windows PowerShell:
    $env:AWS_SDK_LOAD_CONFIG=1
    node 你的脚本文件名.js
    

3. 修复文件内容上传错误

代码中使用JSON.stringify(data, null, 2)处理读取的文件数据,而fs.readFile默认返回Buffer,直接转JSON会导致上传的文件内容被篡改。应直接使用读取到的Buffer作为Body:

const params = {
    Bucket: 'bucket-test',
    Key: 'contacts.csv',
    Body: data // 直接用读取到的Buffer,无需JSON.stringify
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:47:48