A 422 Unprocessable Entity error means an API received your request, understood its format, but could not carry out the instructions inside it. In transactional email systems, that usually points to a validation problem in your message payload, sender identity, recipient data, template variables, account state, or domain configuration—not a temporary delivery failure.

The name can be confusing. The current HTTP specification calls status 422 Unprocessable Content, while many frameworks, libraries, dashboards, and API documents still call it Unprocessable Entity. In either case, the practical meaning is the same: your HTTP request is structurally valid enough to parse, but one or more values fail the service's business rules.

This guide explains how to diagnose 422 responses methodically, how they differ from neighboring HTTP and SMTP errors, and how email-specific configuration—especially domains and DNS—can cause a request to be rejected before a message is accepted for delivery.

What a 422 Unprocessable Entity error means

HTTP status codes answer different questions at different layers. A 422 response is typically an application-level validation response.

The server has usually confirmed all of the following:

  • It received a request at a valid endpoint.
  • It recognized the HTTP method, such as POST.
  • It understood the body format, commonly JSON.
  • It was able to parse the JSON successfully.
  • It found one or more values that are invalid, incomplete, inconsistent, unauthorized for the requested operation, or otherwise impossible to process.

For an email sending API, that could mean a syntactically valid JSON object contains an invalid from address, an empty recipient list, a template variable with the wrong type, an unverified sending domain, or a message body that violates the provider's policy.

Consider this simplified request:

POST /v1/send HTTP/1.1
Authorization: Bearer REDACTED
Content-Type: application/json

{
  "from": "Support <support@example.com>",
  "to": ["customer@example.net"],
  "subject": "Your receipt",
  "html": "<p>Thanks for your order.</p>"
}

If example.com is not an approved sender domain, the provider may reply with something like:

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "error": "validation_error",
  "message": "The sender domain is not verified.",
  "field": "from"
}

The request is valid JSON. It may even have valid email-address syntax. But the API cannot process the request under its sender-domain rules.

Why email APIs commonly use 422

Transactional email providers need to reject questionable requests before accepting mail into their sending queues. That protects recipients, sender reputation, and the provider's infrastructure. An API may therefore validate far more than JSON shape:

  • Sender address ownership or domain verification
  • Recipient address formatting
  • Suppression-list status
  • Template existence and variable requirements
  • Attachment encoding and size
  • Message header safety
  • Account permissions, sandbox restrictions, or sending limits
  • Compliance and anti-abuse rules

Some providers use 400 Bad Request, 403 Forbidden, or provider-specific error structures for these situations instead. Do not rely only on the numeric code. Read the response body, request ID, error code, and field-level details.

422 vs. 400, 401, 403, 415, 429, and 5xx errors

Correct classification matters because each status code suggests a different repair strategy. Retrying every non-2xx response is one of the fastest ways to create duplicate sends, noisy logs, and avoidable rate-limit problems.

422 vs. 400 Bad Request

A 400 Bad Request generally means the server could not interpret the request as sent. Common examples include malformed JSON, invalid URL encoding, a missing required HTTP header, or a body that does not match the declared content type.

{
  "from": "sender@example.com",
  "to": ["recipient@example.net"],
  "subject": "Hello",
}

The trailing comma makes this invalid JSON. An API is more likely to return 400 than 422 because parsing failed before semantic validation could begin.

By contrast, this is valid JSON but may yield a 422:

{
  "from": "sender@example.com",
  "to": [],
  "subject": "Hello"
}

The server can parse it, but an empty recipient array is not a processable email message.

422 vs. 401 Unauthorized and 403 Forbidden

A 401 Unauthorized normally indicates missing, expired, malformed, or invalid authentication credentials. Check the Authorization header, API key environment variable, token scope, and server clock if your authentication scheme uses signed timestamps.

A 403 Forbidden usually means the credentials are recognized but are not permitted to perform the action. For example, an API key may be restricted to a project, environment, account, IP range, or sending domain.

Some APIs may return 422 for a sender domain that is not authorized for your account, while others return 403. Treat the provider's machine-readable error code and message as the authoritative clue.

422 vs. 415 Unsupported Media Type

A 415 Unsupported Media Type is about the format you claim to be sending. A typical cause is sending JSON without the correct content type:

Content-Type: text/plain

If the endpoint expects JSON, use:

Content-Type: application/json

A 422 happens later: the endpoint accepts JSON, parses it, and rejects its meaning.

422 vs. 429 Too Many Requests

A 429 Too Many Requests is a throttling signal. It may include a Retry-After header or provider-specific rate-limit headers. A 422 should usually be fixed, not retried. A 429 should usually be delayed and retried according to the provider's guidance.

422 vs. 500, 502, 503, and 504

A 5xx response indicates a server-side or upstream failure. A carefully designed sender should retry eligible 5xx responses with exponential backoff and a bounded retry window. But first make sure your send operation is idempotent: if the server accepted the message but the client timed out before receiving the response, a blind retry can create a duplicate email.

A 422 is different. Repeating exactly the same invalid payload will normally produce exactly the same response.

Start with the complete error response

Do not debug from the status code alone. Capture the full HTTP exchange while removing secrets and personal data from logs.

For every failed request, record:

  1. The endpoint, HTTP method, and timestamp.
  2. The response status and response body.
  3. Response headers, particularly request or trace IDs.
  4. The request headers except credentials.
  5. The exact payload shape, with recipient addresses and tokens redacted where necessary.
  6. The application version, deployment environment, and API client version.

A useful sanitized log record might look like this:

status=422
request_id=req_01HXYZ...
error=validation_error
field=template_data.invoice_total
message=Expected a string, received number
endpoint=POST /v1/email/send
environment=production

The response body's field, path, code, details, or errors property is often more useful than the top-level message. Validation frameworks frequently return nested paths such as personalizations[0].to[2].email or attachments[0].content.

Reproduce the request outside your application

Reproduce the failing request using curl, Postman, Insomnia, or a minimal script. This separates an API problem from an application serialization, environment-variable, proxy, or library issue.

curl --request POST "https://api.example-email-provider.test/v1/send" \
  --header "Authorization: Bearer $EMAIL_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "Billing <billing@example.com>",
    "to": ["recipient@example.net"],
    "subject": "Receipt",
    "text": "Your receipt is ready."
  }'

Use a test recipient you control. Avoid pasting live API keys into terminal histories, tickets, browser-based tools, or shared chat logs.

If curl succeeds but your application fails, compare the outgoing requests byte for byte where possible. Frequent differences include:

  • A missing Content-Type: application/json header
  • Double-encoded JSON
  • null values emitted where the API expects omitted fields
  • A number sent where a template expects a string
  • Different environment variables in local, staging, and production deployments
  • Unicode normalization or line-ending changes in a generated message

Reduce to the smallest valid message

When an API returns a broad validation error, remove optional features until you have the smallest plausible send:

{
  "from": "sender@example.com",
  "to": ["you@example.net"],
  "subject": "Test",
  "text": "Test message"
}

Then add one component at a time: display name, HTML body, reply-to, tags, metadata, attachments, scheduled delivery, template ID, and template data. This binary-search style approach identifies whether the invalid element is a particular field or an interaction between fields.

Common payload problems that lead to 422 responses

Email payloads look simple until an application starts handling names, multiple recipients, personalized templates, attachments, and generated HTML. The following issues are among the most common causes.

Invalid or ambiguous sender addresses

Use a properly formed mailbox address and make sure the domain is one you are allowed to send from. This is valid formatting:

Billing Team <billing@example.com>

These are common problems:

billing@example                 # no top-level domain
Billing <billing@example.com    # missing closing bracket
billing @example.com            # whitespace in address
billing@example.com, sales@example.com  # two mailboxes in a single sender field

The From header represents the visible author of a message. Many providers require that its domain be verified, and some restrict the local part or display name in certain account states. If you need replies handled elsewhere, use a separate Reply-To field rather than putting multiple addresses into From.

Recipient array and address-object mistakes

Different APIs accept either strings or objects for recipients. A generic string form may look like this:

"to": ["ada@example.net", "linus@example.org"]

An object-based API might require this shape instead:

"to": [
  {"email": "ada@example.net", "name": "Ada Lovelace"}
]

Do not assume the forms are interchangeable. An array of strings may be valid JSON but fail a schema that expects objects. Conversely, an object with address when the API expects email can lead to a 422 field validation error.

Before an address reaches the API, remove accidental whitespace and validate basic syntax. Do not confuse syntax validation with mailbox verification: person@example.com can be syntactically valid yet nonexistent, disposable, or suppressed. For pre-send checks, use an address validation service or a tool such as the email address verification tool, then still handle bounces and suppressions after sending.

Missing message content

Most providers require at least one usable content part, commonly plain text, HTML, or a template reference. A request with a subject but no body may be rejected.

{
  "from": "sender@example.com",
  "to": ["recipient@example.net"],
  "subject": "Status update"
}

A robust transactional message usually includes both plain-text and HTML alternatives:

{
  "from": "sender@example.com",
  "to": ["recipient@example.net"],
  "subject": "Your order has shipped",
  "text": "Your order has shipped. Track it at https://example.com/orders/123.",
  "html": "<p>Your order has shipped.</p><p><a href=\"https://example.com/orders/123\">Track your order</a></p>"
}

Even if a provider accepts HTML-only mail, plain text remains useful for accessibility, fallback clients, security-conscious recipients, and debugging.

Invalid template identifiers or template data

Template sends commonly fail when the template ID is missing, belongs to another environment, has been deleted, or expects variables not included in your payload.

Suppose a template expects first_name, invoice_number, and amount_due. This could fail if amount_due is absent:

{
  "template_id": "invoice-reminder",
  "data": {
    "first_name": "Mina",
    "invoice_number": "INV-1042"
  }
}

It can also fail if a value has the wrong type:

{
  "data": {
    "first_name": "Mina",
    "invoice_number": "INV-1042",
    "amount_due": 42.5
  }
}

Whether a number is allowed depends on the template engine. If the API specifies a string, send "42.50" or use a deliberate currency-formatting step in application code. Formatting currency, time zones, dates, and localized copy before rendering generally produces more predictable email output.

Attachments with invalid encoding or metadata

Attachments are a frequent source of 422 errors because APIs may require base64-encoded content, a filename, MIME type, and a particular object structure.

A generic attachment object could look like this:

{
  "filename": "receipt.pdf",
  "content_type": "application/pdf",
  "content": "JVBERi0xLjQKJc..."
}

Potential failures include:

  • Base64 content contains line breaks or invalid characters for a strict decoder.
  • The attachment exceeds the provider's message or attachment size limit.
  • The declared MIME type conflicts with the file content or is disallowed.
  • The filename is empty or contains unsafe control characters.
  • Your code sends a file path, buffer object, or data URL when the API expects base64 only.

Calculate encoded size, not only original file size. Base64 increases data size by roughly one-third, and the full MIME message adds headers and boundaries. A 19 MB source file can become too large for a 20 MB message limit after encoding.

Sender-domain verification, DNS, and 422 errors

A sending API can reject a message with 422 before delivery if the From domain has not been verified, is pending verification, has failed DNS checks, or does not match an authorized domain. That is an API acceptance problem, not a recipient-server rejection.

Your provider should supply exact DNS hostnames and values for its verification process. Copy those values exactly; do not substitute generic examples below for provider-issued records. DNS providers often append your zone name automatically, so entering a full hostname in a field that expects only the host label can accidentally create a duplicated name such as selector._domainkey.example.com.example.com.

SPF syntax and common mistakes

SPF is published as a DNS TXT record at the sending domain. A simple example is:

example.com. IN TXT "v=spf1 ip4:192.0.2.10 include:spf.email-service.example -all"

This example authorizes the IPv4 address 192.0.2.10 and the policy referenced by spf.email-service.example; all other sources fail SPF. The actual include: domain must come from your provider, and 192.0.2.10 is a documentation address, not a real sending IP to copy into production.

Important SPF rules:

  • Publish one SPF TXT record beginning with v=spf1 for a domain.
  • Merge mechanisms from all legitimate sending services into that single record.
  • Keep -all, ~all, or another all mechanism at the end.
  • Account for DNS-query limits created by nested include, a, mx, redirect, and exists mechanisms.
  • Do not add a second v=spf1 TXT record just because you added another sender.

Two independent SPF records can produce an SPF permerror, which can undermine SPF evaluation and DMARC alignment. Use a DNS inspection tool such as MXToolbox or dig to view the published record:

dig +short TXT example.com

DKIM record syntax

DKIM uses a selector-specific TXT record. A provider may ask you to publish a record resembling:

selector1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."

The selector, key type, and public key value are provider-specific. Do not change the selector or split the value manually unless your DNS provider requires quoted segments for a long TXT record. DNS interfaces may display long values in multiple quoted strings; DNS resolvers concatenate those strings as one TXT record.

Some services use CNAME records for DKIM delegation instead of a direct TXT key, for example:

selector1._domainkey.example.com. IN CNAME selector1.domainkey.provider.example.

Use the record type the provider explicitly requests. A CNAME is not interchangeable with a TXT record, even if the hostname looks similar.

DMARC syntax and alignment

DMARC is published at _dmarc as a TXT record. A cautious monitoring record might look like:

_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"

A stricter policy could look like:

_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; adkim=s; aspf=s"

DMARC requires an aligned SPF or DKIM result. Strict alignment (adkim=s or aspf=s) can be appropriate in some environments, but it may cause unexpected failures when a provider sends with a related but not identical domain. Review aggregate reports before moving from p=none to p=quarantine or p=reject.

DMARC itself does not normally cause a send API to return 422. However, a provider may require a verified domain, may validate supplied authentication records, or may refuse a configuration that is internally inconsistent. Separately, recipient servers can reject or spam-folder mail after acceptance when authentication and alignment are weak.

Verify DNS from the public internet

A record appearing in your DNS dashboard is not proof that it resolves publicly. Check externally after saving changes:

dig +short TXT _dmarc.example.com
dig +short TXT selector1._domainkey.example.com
dig +short CNAME selector1._domainkey.example.com

Query the record type your provider requested. For example, querying TXT for a hostname that should be a CNAME can send you down the wrong debugging path.

DNS propagation timing depends on authoritative nameservers, TTL values, caches, and the provider's verification schedule. Avoid repeatedly changing records while troubleshooting: every edit can reset cache behavior and make it harder to identify which value is actually live.

SMTP relay errors are not HTTP 422 errors

When you send through SMTP, you do not receive HTTP status 422. SMTP uses its own three-digit reply codes and enhanced status codes. Your application may translate an SMTP failure into an exception or a generic error object, but the underlying protocol response remains different.

A simplified SMTP transaction is:

C: EHLO app.example.com
S: 250-mail.example-smtp-provider.test
C: MAIL FROM:<billing@example.com>
S: 250 2.1.0 OK
C: RCPT TO:<customer@example.net>
S: 250 2.1.5 OK
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: Subject: Receipt
C:
C: Thanks.
C: .
S: 250 2.0.0 Queued as abc123

If the relay refuses an unauthorized sender, you might see an SMTP response such as 550 5.7.1, 553 5.7.1, or another provider-specific permanent failure. If the recipient mailbox does not exist, a downstream server commonly returns a 550 class response, often with enhanced code 5.1.1.

How to interpret SMTP classes

The first digit is the most important starting point:

  • 2xx: success; the command was accepted.
  • 4xx: transient failure; retry may succeed later.
  • 5xx: permanent failure; change something before retrying.

Examples:

421 4.7.0 Temporary system problem
450 4.2.0 Mailbox unavailable or temporarily busy
452 4.2.2 Insufficient system storage
550 5.1.1 Recipient address rejected
554 5.7.1 Message rejected for policy reasons

The text after the code is not standardized enough to parse as your primary integration contract. Log it because it is valuable for humans, but make retry decisions primarily from the response class, enhanced status code when available, and provider documentation.

A REST API may return 202 Accepted or 200 OK after queuing a message, then later record an SMTP or recipient-side delivery failure. This distinction is critical: successful API acceptance does not guarantee inbox delivery.

A systematic 422 troubleshooting workflow

Use this sequence to eliminate causes without changing several variables at once.

1. Confirm the request route and method

Check that your application is calling the intended API base URL, endpoint version, and HTTP method. A staging endpoint, legacy endpoint, or incorrect regional endpoint can validate a payload differently from production.

2. Check headers and JSON serialization

Verify Content-Type: application/json, authorization, character encoding where relevant, and the actual serialized body. Log the outgoing JSON after your SDK or HTTP client has processed it, not only the source object before serialization.

3. Read field-level validation details

Look for the path and machine-readable code in the response. If the API says from.domain, do not spend time debugging recipients. If it says template_data.customer.name, inspect the value and expected type.

4. Send a minimal message

Use one verified sender, one recipient you control, a short ASCII subject, and plain text only. If that succeeds, add optional fields incrementally.

5. Verify sender authorization and domain status

Confirm that the exact domain in From is approved for the active account and environment. notifications@example.com and notifications@mail.example.com are different domains for verification and alignment purposes.

6. Validate public DNS records

Use dig, MXToolbox, or a comparable DNS lookup tool to inspect SPF, DKIM, and DMARC records from outside your DNS provider's UI. Compare the live values with the values issued by the email service.

7. Review templates, attachments, and personalization

Check deleted or unpublished templates, missing variables, null values, attachment encoding, and attachment size. Test a static message first, then test the exact dynamic data that failed.

8. Use request IDs when contacting support

If the error remains unclear, provide the timestamp in UTC, request ID, endpoint, sanitized response body, and sanitized payload. That gives the provider enough information to find the rejected request without exposing your API key or customer data.

For provider-specific field names, endpoint paths, and send examples, consult the service's email API reference and setup guides rather than extrapolating from another vendor's SDK.

Prevent 422 errors before deployment

The best 422 incident is one your application catches before it sends a request. Add validation at the boundary where your business data becomes an email payload.

Use a typed message schema

Whether you use TypeScript, Python, Go, Ruby, Java, or another language, define a schema for the message your application sends. Validate required fields, arrays, enums, lengths, attachment metadata, and template data before calling the email API.

For example, application-level rules might include:

  • from must use an approved domain.
  • to must contain at least one recipient.
  • subject must be non-empty and below an internal length limit.
  • At least one of text, html, or template_id must be present.
  • template_id and raw content cannot be combined if your provider disallows that combination.
  • Attachments must have a filename, content type, and valid base64 data.

Client-side validation does not replace server-side validation. It does give developers clearer errors, reduces unnecessary API calls, and makes invalid states harder to ship.

Test production-like configuration

Many 422 problems appear only after deployment because development uses a different sender domain, template set, API key, or account permission model. Include an integration test that sends to a controlled inbox from the same type of sender domain and credentials used in production.

Use a dedicated test subdomain such as mail.example.com or staging.example.com where appropriate. Keep its DNS and verification configuration intentional; do not assume production authentication automatically applies to every subdomain.

Monitor validation failures separately

A 422 is usually an engineering or configuration signal, not a transient infrastructure event. Track it separately from network failures, rate limits, deferred deliveries, bounces, and spam complaints.

Useful metrics include:

  • 422 rate by endpoint and application release
  • Top failing field paths
  • Failures by sender domain
  • Failures by template ID
  • Attachment-related validation failures
  • Validation errors by environment

A sudden increase immediately after a deployment often indicates an application serialization or schema change. A gradual increase around a particular sender domain may indicate a DNS, authorization, or configuration drift problem.

Deliverability checks after the 422 is fixed

Fixing a 422 only means the provider accepted your request. You still need to confirm that messages authenticate, render, and reach a mailbox as expected.

Send a test to a controlled inbox and inspect the delivered message headers. Look for SPF, DKIM, and DMARC results. Test both HTML and text rendering, links, unsubscribe behavior for non-transactional mail, and reply handling.

Tools such as mail-tester.com can help inspect a test message for content and configuration issues, while MXToolbox can help inspect public DNS records. Treat tool scores as diagnostic signals, not as a substitute for monitoring real inbox placement, bounces, complaints, and authentication reports.

Also distinguish acceptance from delivery in your product telemetry. A send API response may confirm that a provider has queued a message; a later webhook, event stream, or activity record is often needed to confirm delivery, bounce, deferral, or suppression.

Conclusion

A 422 Unprocessable Entity response is usually good news in one narrow sense: the server understood enough of your request to tell you that the problem is specific and fixable. It is not a network outage, and it is rarely a reason to retry unchanged.

Start with the response body and request ID, reproduce the smallest message possible, then inspect sender authorization, recipient structure, message content, template data, attachments, and DNS-backed domain verification. Keep HTTP API acceptance separate from SMTP relay responses and separate again from final recipient delivery. That layered approach turns a vague validation failure into a short, repeatable debugging process.

FAQ

Should I retry a 422 Unprocessable Entity error?

Usually no. A 422 normally indicates a deterministic validation or business-rule failure. Fix the payload, sender authorization, template data, or configuration first. Retrying unchanged input is unlikely to help and can create unnecessary load.

Is a 422 error the same as an SMTP 550 error?

No. A 422 is an HTTP API response. A 550 is an SMTP permanent failure response, often associated with a rejected recipient or policy decision. Both can block a send, but they occur at different protocol layers and need different diagnostics.

Can an SPF, DKIM, or DMARC issue cause a 422?

It can indirectly. A sending API may reject a message if the sender domain is unverified or required DNS records are missing. More commonly, SPF, DKIM, and DMARC problems affect delivery or spam placement after the API has accepted the message.

Why does valid JSON still return 422?

JSON validity only proves that the body can be parsed. A 422 means the parsed data violates an API rule, such as an unverified From domain, missing template variable, empty recipient list, unsupported attachment, or invalid field combination.

What should I send provider support for an unexplained 422?

Send the UTC timestamp, request ID, endpoint, HTTP status, complete sanitized response body, and a sanitized version of the payload. Never include your API key, authentication token, or unredacted customer data.