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

Vercel部署Next.js API调用AWS S3 SDK上传报ERR_HTTP_HEADERS_SENT错误

Next.js API在Vercel部署后调用@aws-sdk/client-s3报ERR_HTTP_HEADERS_SENT错误的解决思路

问题场景

本地环境下,Next.js API端点使用@aws-sdk/client-s3包可正常上传文件至S3,但部署到Vercel后,SDK抛出ERR_HTTP_HEADERS_SENT错误。此前该功能曾正常工作,且S3桶中仍保留当时成功上传的文件。

代码示例

import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const s3Client = new S3Client({});

  const uploadCommand = new PutObjectCommand({
    Bucket: process.env.MY_S3_BUCKET,
    Key: "test/testUpload.json",
    Body: JSON.stringify({ message: "Hello World" }),
  });

  const response = await s3Client.send(uploadCommand);

  res.status(200).json(response);
}

错误信息

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (node:internal/errors:399:5)
    at ClientRequest.setHeader (node:_http_outgoing:663:11)
    at mod.request (/var/task/___vc/__launcher.js:90:17)
    at /var/task/node_modules/@aws-sdk/node-http-handler/dist-cjs/node-http-handler.js:70:25
    at new Promise (<anonymous>)
    at NodeHttpHandler.handle (/var/task/node_modules/@aws-sdk/node-http-handler/dist-cjs/node-http-handler.js:49:16)
    at async /var/task/node_modules/@aws-sdk/middleware-serde/dist-cjs/deserializerMiddleware.js:5:26 {
  code: 'ERR_HTTP_HEADERS_SENT',
  '$metadata': { attempts: 1, totalRetryDelay: 0 }
}

使用的包版本

"@aws-sdk/client-s3": "3.278.0",

可能原因

该错误本质是HTTP响应已发送给客户端后,代码仍尝试修改响应头。在Vercel无服务器环境下,主要触发原因包括:

  • AWS SDK默认的NodeHttpHandler与Vercel的请求处理运行时存在冲突,Vercel的运行时可能提前终止请求上下文,导致SDK后续的头信息操作失效。
  • 旧版本@aws-sdk/client-s3存在与Vercel Node.js环境兼容的bug,后续版本已修复相关问题。
  • 未捕获的异常导致代码路径重复发送响应。

解决方案

1. 替换HTTP Handler为FetchHttpHandler

使用AWS SDK提供的FetchHttpHandler替代默认的NodeHttpHandler,适配Vercel环境对Fetch API的良好支持,避免Node原生HTTP模块的冲突。

修改后的代码:

import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { FetchHttpHandler } from "@aws-sdk/fetch-http-handler";
import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  try {
    const s3Client = new S3Client({
      requestHandler: new FetchHttpHandler(),
    });

    const uploadCommand = new PutObjectCommand({
      Bucket: process.env.MY_S3_BUCKET,
      Key: "test/testUpload.json",
      Body: JSON.stringify({ message: "Hello World" }),
    });

    const response = await s3Client.send(uploadCommand);

    res.status(200).json(response);
  } catch (error) {
    res.status(500).json({ error: (error as Error).message });
  }
}

2. 升级@aws-sdk/client-s3到最新稳定版

旧版本(如3.278.0)存在已知的环境兼容问题,升级至最新稳定版可修复HTTP handler相关的bug:

npm install @aws-sdk/client-s3@latest

3. 确保请求上下文的单一响应

用try/catch包裹所有异步操作,确保无论成功或失败,仅发送一次HTTP响应,避免未捕获异常导致Vercel运行时额外触发响应操作。

4. 对齐Vercel与本地的Node.js版本

检查Vercel项目设置中的Node.js版本,确保与本地开发环境一致(例如均使用Node 18),避免版本差异导致的SDK行为不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:20:19