Amazon SES
SendEmail operation
email error
illegal address
troubleshooting email

Error on amazon SES SendEmail operation Illegal addres

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Amazon SES rejects a SendEmail request with an "Illegal address" error when one of the email fields is malformed before delivery even starts. The failure usually has nothing to do with quotas or message content; it is almost always caused by a bad From, To, Cc, Bcc, or Reply-To value in the API request.

What SES Is Validating

SES expects each address to be a syntactically valid email address. In the simple SendEmail API, the fields are submitted as structured values, not as raw MIME headers, so the safest pattern is to send plain mailbox addresses such as [email protected].

Typical causes include:

  • leading or trailing whitespace
  • commas, semicolons, or accidental newline characters
  • display-name formatting passed where only an address is expected
  • empty strings inside a recipient list
  • template data producing None, null, or partial addresses

For example, this looks harmless but is a common source of failure:

python
recipients = ["[email protected]", "", " [email protected] "]

The blank string and padded whitespace can easily become an SES validation error.

A Safe Way to Prepare Addresses

Before sending, normalize and validate every address that your application generates. Python's standard library can help with basic parsing, and you can reject obviously invalid values before calling AWS.

python
1from email.utils import parseaddr
2
3
4def normalize_address(value: str) -> str:
5    display_name, address = parseaddr(value.strip())
6    if not address or "@" not in address:
7        raise ValueError(f"Invalid email address: {value!r}")
8    return address
9
10
11def normalize_recipient_list(values: list[str]) -> list[str]:
12    cleaned = []
13    for value in values:
14        if not value or not value.strip():
15            continue
16        cleaned.append(normalize_address(value))
17    if not cleaned:
18        raise ValueError("No valid recipients were provided")
19    return cleaned

This does not implement a full RFC parser, but it catches the majority of application-level mistakes that lead to SES failures.

Sending with boto3

Once your addresses are normalized, keep the SES request simple. Avoid inserting display-name formatting unless you are intentionally building a raw MIME email through a different SES API.

python
1import boto3
2
3
4ses = boto3.client("ses", region_name="us-east-1")
5
6source = normalize_address("[email protected]")
7to_addresses = normalize_recipient_list([
8    "[email protected]",
9    "[email protected]",
10])
11
12response = ses.send_email(
13    Source=source,
14    Destination={
15        "ToAddresses": to_addresses,
16    },
17    Message={
18        "Subject": {
19            "Data": "Welcome",
20            "Charset": "UTF-8",
21        },
22        "Body": {
23            "Text": {
24                "Data": "Thanks for signing up.",
25                "Charset": "UTF-8",
26            }
27        },
28    },
29)
30
31print(response["MessageId"])

If this fails with an illegal address message, log the exact addresses being submitted after normalization. That is usually faster than inspecting higher-level template code.

Distinguishing Address Errors from Other SES Problems

SES has several failure modes that people often mix together. A sandbox restriction, an unverified identity, or a region mismatch may prevent delivery, but those issues produce different errors. "Illegal address" is specifically about address parsing or invalid field contents.

That distinction matters during debugging. If the exception says illegal address, do not start by checking DKIM or IAM permissions. Start by printing the exact Source, ToAddresses, CcAddresses, BccAddresses, and ReplyToAddresses values that the SDK is sending.

In JavaScript, a small cleanup layer before the AWS SDK call is equally useful:

javascript
1function cleanAddresses(values) {
2  return values
3    .map((value) => value.trim())
4    .filter((value) => value.length > 0);
5}
6
7const toAddresses = cleanAddresses([
8  "[email protected]",
9  " [email protected] ",
10]);

Even simple trimming prevents a surprising number of failures in form-driven applications.

Common Pitfalls

One frequent mistake is passing a comma-separated string where the SDK expects an array. Some developers build [email protected],[email protected] and send it as one item. SES then treats that entire string as a single invalid address.

Another issue is mixing display names with the simple API. A value like "Alice Example" <[email protected]> may parse in some contexts, but if your code is inconsistent across fields, the safest solution is to normalize to the mailbox address only.

Template expansion can also create broken addresses silently. If customer.email is missing, your code may generate an empty value and still include it in the destination list. Validate after template rendering, not before.

Finally, avoid logging only the raw exception. If you do not capture the cleaned request values, you can spend a long time inspecting unrelated email logic while the real problem is a single malformed string.

Summary

  • SES "Illegal address" errors are usually caused by malformed From or recipient values.
  • Normalize and validate addresses before calling SendEmail.
  • Send plain mailbox addresses in the simple API unless you intentionally need raw MIME behavior.
  • Log the final values submitted to SES so you can find empty strings, whitespace, or malformed entries quickly.
  • Do not confuse address validation failures with identity verification, sandbox, or permission problems.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.