How to Fix Resend Node SDK validation_error 403 Forbidden
Quick Diagnosis
- ✓ Are you attempting to send an email to an external customer using the default
onboarding@resend.devsender? - ✓ Does your API request throw a
403 Forbiddenresponse containing avalidation_errorexception token? - ✓ Did you specify a custom sender address in the
fromfield whose domain is unverified in your Resend Dashboard?
Environment
The Resend SDK handles server-side mail routing across environments including Next.js Route Handlers, Express Server Contexts, Serverless Vercel Functions, and Custom Node API Endpoints.
| Domain Configuration | Sender Email Address | Recipient Constraint | API Execution Outcome |
|---|---|---|---|
| Unverified custom domain | user@unverified.com |
Any email address | validation_error 403 (Domain not verified) |
| Default Sandbox | onboarding@resend.dev |
Owner email address | Success (Testing mode) |
| Default Sandbox | onboarding@resend.dev |
External customer email | validation_error 403 (Sandbox restriction) |
| Verified custom domain | contact@verified.com |
Any email address | Success (Production mode) |
Minimal Repro
When you send an email via Resend API, the service enforces strict domain validation criteria to protect email domains from spoofing and ensure delivery alignment under SPF, DKIM, and DMARC protocols. When using the default sandbox sender address (onboarding@resend.dev), Resend implements a restricted routing policy that allows messages to deliver only to the verified account owner’s email address. Attempting to send to any external address or using a custom domain that is not marked as verified in the Resend dashboard triggers a validation block. The API server intercepts this mismatch during the request authentication phase and aborts the request, returning a 403 Forbidden error with the validation_error exception token. To allow external sending, you must register the domain and update DNS public records.
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
export async function sendEmail() {
// CRASH: Sending from onboarding@resend.dev to an external customer email
const data = await resend.emails.send({
from: 'onboarding@resend.dev',
to: 'customer@externaldomain.com',
subject: 'Hello Customer',
html: '<p>Welcome to our service!</p>'
});
return data;
}
ResendError: validation_error (Status Code: 403)
"You can only send emails to your own email address while in sandbox mode. Verify your custom domain to send to other recipients."
Resolution
When resolving Resend validation errors, developers can choose between two main structural options depending on their deployment target.
Option A: Restrain Recipients for Sandbox Testing
If you are developing or testing, keeping your sender address configured as onboarding@resend.dev is applicable, provided you restrict the recipient list strictly to your registered account owner’s email address.
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
export async function sendSandboxEmail() {
// Success: Sending to the verified account owner address
const data = await resend.emails.send({
from: 'onboarding@resend.dev',
to: 'owner@registeredemail.com',
subject: 'Sandbox Notification',
html: '<p>Diagnostic trace completed.</p>'
});
return data;
}
Option B: Verify a Custom Domain for Production Sending
If you are preparing for production deployment, verifying a custom domain you own prevents sandbox sending restrictions and allows emailing external customers.
- Add your domain inside the Resend Domains dashboard to export the required SPF and DKIM public records.
- Register the specific TXT and MX records inside your registrar’s DNS settings panel.
- Once records propagate, update your application code to send from your custom domain.
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
export async function sendProductionEmail(recipient) {
// Success: Sending to any recipient from a verified domain
const data = await resend.emails.send({
from: 'no-reply@verifieddomain.com',
to: recipient,
subject: 'Production Notification',
html: '<p>Official notification content.</p>'
});
return data;
}
When This Fix Won’t Work
If you added your DNS records but local caches have not yet propagated, Resend dashboard verification check requests can fail. In this case, allow time for propagation or restart the verification checks within the Resend console.
Operational Runbook
Case 1: Testing & Development Environments
- Revert sender parameters in code to
onboarding@resend.dev. - Restrict recipient targets to the registered admin email address.
Case 2: Production Environments
- Register custom domains inside Resend domains setup.
- Bind the generated SPF and DKIM records to your registrar DNS configs.
Rollback Strategy
To roll back this change, restore the previous email sender configuration by replacing custom sender addresses in the from field with the default sandbox address (onboarding@resend.dev), constrain target recipients strictly to the registered account owner’s address, and remove custom domain verification assets from the application codebase.
Verification
- Application mail dispatch requests complete returning HTTP 200 responses containing generated email message IDs.
- Public DNS propagation query tools return active TXT records matching Resend SPF and DKIM public keys.
- Resend administration dashboard displays verified status indicators for the target custom domain.
Error Trigger Point Lifecycle
Add domain in Resend console ➔ Configure DNS TXT records ➔ Wait for DNS propagation ➔ Initialize Resend client ➔ Call emails.send API [ERROR OCCURS HERE] ➔ Verify email delivery
References
- Resend Domains Guide: https://resend.com/docs/dashboard/domains/introduction
- Evidence Tier: Official
- Contribution: Verified the Resend domain registration schema parameters, API migration paths, and structural signature modifications.
- Resend DNS Record Configuration Reference: https://resend.com/docs/dashboard/domains/dns-configuration
- Evidence Tier: Official
- Contribution: Verified the email sender verification rules, DNS propagation parameters, and dynamic routing records.
- Resend GitHub Issue #482: https://github.com/resend/resend-node/issues/482
- Evidence Tier: Community
- Contribution: Captured the real-world execution symptoms and reproduction parameters of the Resend 403 validation_error.