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

Lambda Node.js用SES sendRawEmail发带附件邮件遇Nested group错误求助

Fixing "InvalidParameterValue: Nested group" Error with SES sendRawEmail in Node.js

Hey there, sorry you're stuck with that "Nested group" error when sending attachments via SES sendRawEmail! I’ve run into this before—it almost always boils down to an invalid MIME message structure that SES can’t parse correctly. Let’s break this down and get your attachments sending smoothly.

Why the Error Happens

The "Nested group" error means SES is seeing an invalid nested MIME multipart structure. Common culprits include:

  • Using the same boundary string for multiple nested multipart sections
  • Nesting multipart groups in a non-standard way (like putting multipart/alternative directly at the top without wrapping it in multipart/mixed when attachments are present)
  • Forgetting to properly close boundary sections with the trailing --

Working Node.js Example (AWS SDK v3)

Here’s a complete, tested example using the latest AWS SDK v3. This builds a valid MIME structure that supports both plain text/HTML content and attachments:

const { SESClient, SendRawEmailCommand } = require("@aws-sdk/client-ses");
const fs = require('fs');
const { Buffer } = require('buffer');

// Initialize your SES client with your region
const sesClient = new SESClient({ region: 'us-east-1' }); // Replace with your region

async function sendEmailWithAttachment() {
  // Create unique boundary strings (ensure they don't appear in your email content!)
  const mainBoundary = '----=_MainBoundary_000_12345ABCDEF';
  const altBoundary = `${mainBoundary}_Alternative`;

  // Read and encode your attachment to base64
  const attachmentPath = './invoice.pdf'; // Replace with your file path
  const attachmentData = fs.readFileSync(attachmentPath);
  const attachmentBase64 = attachmentData.toString('base64');

  // Build the full MIME message (follow MIME standards strictly!)
  const mimeContent = [
    `From: "Your Name" <your-email@example.com>`,
    `To: "Recipient Name" <recipient-email@example.com>`,
    `Subject: Your Invoice Attached`,
    `MIME-Version: 1.0`,
    `Content-Type: multipart/mixed; boundary="${mainBoundary}"`,
    ``,
    `This is a multi-part message in MIME format.`,
    ``,
    // Start the alternative section (plain text + HTML)
    `--${mainBoundary}`,
    `Content-Type: multipart/alternative; boundary="${altBoundary}"`,
    ``,
    `--${altBoundary}`,
    `Content-Type: text/plain; charset="UTF-8"`,
    ``,
    `Hi there,`,
    ``,
    `Please find your invoice attached to this email.`,
    ``,
    `Thanks,`,
    `Your Team`,
    ``,
    `--${altBoundary}`,
    `Content-Type: text/html; charset="UTF-8"`,
    ``,
    `<h3>Hi there,</h3>`,
    `<p>Please find your invoice attached to this email.</p>`,
    `<p>Thanks,<br>Your Team</p>`,
    ``,
    `--${altBoundary}--`,
    ``,
    // Start the attachment section
    `--${mainBoundary}`,
    `Content-Type: application/pdf; name="invoice.pdf"`, // Match your file type
    `Content-Disposition: attachment; filename="invoice.pdf"`,
    `Content-Transfer-Encoding: base64`,
    ``,
    attachmentBase64,
    ``,
    // Close the main boundary
    `--${mainBoundary}--`
  ].join('\r\n'); // Critical: Use CRLF line breaks for MIME compliance

  // Send the raw email
  try {
    const command = new SendRawEmailCommand({
      RawMessage: {
        Data: Buffer.from(mimeContent)
      }
    });
    const response = await sesClient.send(command);
    console.log(`Email sent! Message ID: ${response.MessageId}`);
  } catch (error) {
    console.error('Error sending email:', error);
  }
}

// Run the function
sendEmailWithAttachment();

Key Things to Note

  1. Boundary Uniqueness: The main boundary and alternative boundary are distinct—this prevents SES from misinterpreting nested groups.
  2. Correct MIME Structure: We wrap the multipart/alternative (plain text + HTML) inside a multipart/mixed container (which holds the alternative content + attachments). This is the standard structure for emails with attachments.
  3. CRLF Line Breaks: MIME requires \r\n line breaks, not just \n. Using .join('\r\n') ensures compliance.
  4. Attachment Encoding: Attachments must be encoded in base64, with matching Content-Type and Content-Disposition headers.

If You’re Using AWS SDK v2

If you’re still on SDK v2, the core logic is the same—just adjust the client initialization and send call:

const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-1' });
const ses = new AWS.SES({ apiVersion: '2010-12-01' });

// ... (build mimeContent same as above)

ses.sendRawEmail({ RawMessage: { Data: mimeContent } }, (err, data) => {
  if (err) console.error(err);
  else console.log('Email sent:', data);
});

Double-check your MIME structure against the example above—this should resolve the "Nested group" error. Let me know if you hit any other snags!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 09:42:43