Introduction
Scratch orgs give Salesforce developers and DevOps engineers ephemeral, clean environments that mirror production, which is why so much development runs through them. Email domain verification is one of the recurring friction points in keeping them usable. Test anything that sends mail, automated email alerts, case-to-email routing, a Marketing Cloud integration, and an unverified domain can stall the testing pipeline entirely.
What follows is the architectural approach: move the configuration into scratch org definition files and CLI automation so an org is delivery-ready the moment it is created, instead of clicking through the Setup UI every time a new one is spun up.
The challenge with ephemeral orgs
Scratch orgs are designed to be temporary. 'Email Domain Filtering' and 'Email Domain Verification' are security measures built for production-level stability. Scratch orgs come up with random base URLs and email addresses, which trips those security protocols, and Salesforce then wants explicit domain verification before it authorizes outgoing email.
If your CI/CD pipeline runs integration tests against external SMTP or an email relay service, an unverified domain gives you 'Transaction Security' failures or emails that disappear silently. Move the configuration into project-scratch-def.json so the environment is 'born' with the settings it needs.
Automating configuration via scratch org definitions
project-scratch-def.json is the most efficient place to handle this. Not every aspect of domain verification can be fully 'activated' there, since that needs a DNS handshake against a real domain, but you can pre-configure the features and cut the manual overhead.
Give the definition file the features and settings blocks that cover organizational email settings. For example:
{
"orgName": "Dev Environment",
"edition": "Developer",
"features": ["StateAndCountryPicklist"],
"settings": {
"emailAdministrationSettings": {
"enableEmailToCase": true,
"enableEmailDomainFiltering": false
},
"securitySettings": {
"enableEmailRelay": true
}
}
}
Setting enableEmailDomainFiltering to false in the scratch org definition bypasses the strictest verification checks during development. It is a common pattern on teams whose work is logic rather than network infrastructure testing.
CLI scripting for domain registration
If the project needs authentic domain verification to test DKIM or SPF records, the JSON definition file alone will not get you there. You have to inject metadata with the Salesforce CLI once the org is provisioned.
A post-creation script (using sfdx force:org:open or sf org open) that pushes the required DomainVerification metadata does the job. Here is a sample using sfdx to handle the activation:
# Step 1: Create the scratch org
sf org create scratch -f config/project-scratch-def.json --alias DevOrg
# Step 2: Push your local domain verification metadata
sf project deploy start --source-dir force-app/main/default/objects/DomainVerification
# Step 3: Trigger the verification process via anonymous Apex
sf apex run --file scripts/apex/verifyDomain.cls
Inside verifyDomain.cls, use the System.Domain and Messaging APIs to map the organizational email addresses to your test domains.
Best practices for DevOps pipelines
A few habits keep environments clean and secure once email verification is part of a professional CI/CD pipeline:
- Use mock services. Most LWC or Apex email logic tests do not need a real domain. Mailtrap or an integrated Salesforce mocking framework will intercept the outgoing SMTP traffic.
- Parameterize the configuration. Environment variables in GitHub Actions or Jenkins let you flip a scratch org definition between 'Production-like' and 'Development-optimized' settings.
- Centralize the metadata. Keep the email relay configuration and domain settings in a dedicated
email-configpackage and deploy it as a dependency to every scratch org. - Clean up after yourself. Scratch orgs are ephemeral, so configure
sfdx-project.jsonto delete domains and aliases on org expiration and keep the footprint down.
Troubleshooting verification errors
If the scratch org is still failing to send emails, check the 'Email Log' from the Setup menu. The culprit is often the 'Organization-Wide Email Address' rather than domain verification itself, because it has not been mapped to the verified domain.
Always check that the user who created the scratch org is set as the 'Default' sender when you are testing automated flows. Your setup script can do that with the sfdx force:data:record:create command, inserting an OrgWideEmailAddress record mapped to your domain.
Leave a Comment