Skip to content

Email headers

Which email headers you can set, which are auto-generated, and how they are validated

When sending emails with Cloudflare Email Service, you can set custom headers using the headers field in the Workers API or REST API. The Email Service uses a whitelist-based approach — only explicitly approved headers are accepted. Any header not on the whitelist (and not an X- prefixed custom header) is rejected at API time with a clear error.

Platform-controlled headers

These headers are auto-generated by the Cloudflare Email Service infrastructure. You cannot set or override them. If you include any of these in the headers object, the API returns E_HEADER_NOT_ALLOWED.

HeaderBehavior
DateUTC timestamp set at acceptance time
Message-IDGenerated with Cloudflare domain for unique tracking
MIME-VersionAlways 1.0
Content-TypeGenerated from body parts provided
Content-Transfer-EncodingGenerated from content analysis
DKIM-SignatureSigned by Cloudflare infrastructure
Return-PathSet to Cloudflare bounce processor
ReceivedAdded per RFC 5321 at each hop
Feedback-IDGenerated for Google Postmaster Tools reputation feedback
ARC-*Authentication chain for forwarding
TLS-RequiredPlatform-controlled delivery infrastructure setting
TLS-Report-DomainTLS failure reports route to Cloudflare infrastructure
TLS-Report-SubmitterReferences Cloudflare sending domain
CFBL-AddressComplaint feedback loop address (RFC 9477)
CFBL-Feedback-IDComplaint feedback loop ID (RFC 9477)

Headers that correspond to first-class API fields — From, To, Cc, Bcc, Subject, Reply-To — are also rejected in the headers object with E_HEADER_USE_API_FIELD. Set these using the dedicated API fields (from, to, cc, bcc, subject, replyTo for Workers / reply_to for REST) instead.

Whitelisted custom headers

These headers can be set via the headers field. Any header not listed here and not starting with X- is rejected with E_HEADER_NOT_ALLOWED.

Threading and reply headers

HeaderRFCNotes
In-Reply-ToRFC 5322Critical for email threading in all clients
ReferencesRFC 5322Critical for email threading in all clients

List management headers

HeaderRFCNotes
List-UnsubscribeRFC 2369Must contain <https://...> and/or <mailto:...> URI(s). HTTP (non-TLS) URIs are rejected. Gmail and Yahoo require this for bulk senders. Always DKIM-signed per RFC 8058.
List-Unsubscribe-PostRFC 8058Must be exactly List-Unsubscribe=One-Click (case-sensitive). Requires List-Unsubscribe with an HTTPS URI.
List-IdRFC 2919List identification
List-ArchiveRFC 2369URL to list archive
List-HelpRFC 2369URL for help
List-OwnerRFC 2369List owner contact
List-PostRFC 2369Address for posting
List-SubscribeRFC 2369Subscribe URL or address
PrecedenceDe facto standardAccepted values: bulk, list, junk

Automated message identification

HeaderRFCNotes
Auto-SubmittedRFC 3834Values: auto-generated, auto-replied, auto-notified

Content and display

HeaderRFCNotes
Content-LanguageRFC 3282Language of content (for example, en, fr)
KeywordsRFC 5322Message keywords (comma-separated for multiple values)
CommentsRFC 5322Additional comments (comma-separated for multiple values)
ImportanceRFC 2156Values: high, normal, low
SensitivityRFC 2156Values: personal, private, company-confidential
OrganizationRFC 4021Sender's organization name

Delivery and notification

HeaderRFCNotes
Require-Recipient-Valid-SinceRFC 7293Address reuse protection

Modern standards

HeaderRFCNotes
Archived-AtRFC 5064URL where message is archived

Custom X-headers

Any header starting with X- is allowed. This covers common headers like X-Mailer, X-Priority, X-Campaign-ID, and any custom tracking headers your application needs.

  • Name format: X-[A-Za-z0-9\-_]+, maximum 100 characters
  • Value: UTF-8, maximum 2,048 bytes
  • No count limit on X-headers (subject to the 16 KB total payload limit)

Usage examples

Terminal window
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: application/json" \
--data '{
"to": "user@example.com",
"from": "notifications@yourdomain.com",
"subject": "Your weekly digest",
"html": "<h1>Weekly Digest</h1>",
"headers": {
"In-Reply-To": "<original-message-id@yourdomain.com>",
"References": "<original-message-id@yourdomain.com>",
"List-Unsubscribe": "<https://yourdomain.com/unsubscribe?id=abc123>",
"List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
"X-Campaign-ID": "weekly-digest-2026-03",
"X-User-Segment": "premium"
}
}'

Header limits

LimitValue
Max whitelisted (non-X) custom headers20
Max header name length100 bytes
Max header value length2,048 bytes
Total custom headers payload16 KB

The total payload is calculated as sum(len(name) + 2 + len(value) + 2) for all custom headers (name + : + value + CRLF). Whitelisted and X-headers are counted together toward this limit.

Validation rules

  1. Header names — ASCII only, no spaces, no colons, 1–100 characters. Whitelisted headers must match [A-Za-z0-9\-]+. X-headers must match X-[A-Za-z0-9\-_]+ (underscores allowed only in X-headers).
  2. Header values — UTF-8 allowed, maximum 2,048 bytes, no bare CR/LF. Empty values are rejected.
  3. Case-insensitive matching — Header names are matched case-insensitively per RFC 5322 §2.2. The canonical casing from the whitelist is used in the generated message.
  4. Proper line folding — Long headers are folded at 78 characters per RFC 5322 using CRLF+WSP, not MIME encoding.
  5. Single occurrence — The headers type is { [key]: string }, so each header name can appear at most once. For headers that support multiple values (such as Keywords or Comments), use comma-separated values in a single string.

Error codes

Error CodeWhenExample message
E_HEADER_NOT_ALLOWEDHeader is platform-controlled or not on the whitelistHeader 'Date' is not allowed. It is auto-generated by the platform.
E_HEADER_USE_API_FIELDHeader corresponds to a first-class API fieldHeader 'From' must be set via the 'from' API field, not the 'headers' object.
E_HEADER_VALUE_INVALIDHeader value is malformed or emptyHeader 'List-Unsubscribe' must contain angle-bracket HTTPS or mailto URI(s).
E_HEADER_VALUE_TOO_LONGHeader value exceeds 2,048 byte limitHeader 'X-Campaign-ID' value exceeds 2048 byte limit.
E_HEADER_NAME_INVALIDHeader name contains invalid characters or exceeds 100 bytesHeader name 'Bad Header!' contains invalid characters.
E_HEADERS_TOO_LARGETotal custom headers payload exceeds 16 KBTotal custom headers payload (17.2KB) exceeds 16KB limit.
E_HEADERS_TOO_MANYToo many whitelisted (non-X) custom headers21 whitelisted headers provided, maximum is 20.