Skip to content

Health checks

Before an email goes out, Flyanote checks it: that it builds, that its merge tags work, that it fits in the inbox, that its links are sound, and that it has what the law requires. Each finding names its check.

How serious a finding is depends on the check and on the email’s category, marketing or transactional. These are the severities:

Reject (reject)
The save is refused and nothing is stored. The API answers 422.
Block (block)
The draft saves, but it can’t be published, scheduled, or sent until it’s fixed. A block marked “also stops a test send” stops that too.
Warning (warning)
Worth a look first. The app asks you to confirm; the API sends and lists it in warnings[].
Tip (info)
A suggestion. It never stops anything.
Our bug (bug)
A block that is our fault, not yours. We’re alerted, your draft is saved, and trying again usually works.
Added for you (applied)
A note that we changed something on our own, such as adding the footer the law requires.

This page is generated from the checks themselves, so it lists exactly the checks we run. Each finding’s docs_url links to its check’s entry here, at #<id-with-dashes>, such as #compliance-identity for compliance.identity.

Building the email

Every email must build. These checks make sure the document is valid, everything it names exists, and what we build from it is sound.

render.schema: The document isn’t valid

The email document doesn’t match the format: a property is missing, misspelled, or the wrong type, or a rule across properties is broken. Each problem has a JSON Pointer and a code from the format’s error catalog.

  • For: marketing, transactional email
  • Runs at: save, validate
  • Version: 5
SeverityWhen
RejectAny problem: the save is refused.

How to fix it

  1. Fix each problem in errors: pointer says where, and its docs_url links to the fix on the email format page.
  2. Check a document without saving it with the validate call.

render.context: Something the email names is missing

The email names something your account doesn’t have: a brand kit color, font, or logo, an uploaded image, a saved link, or a merge tag Liquid can’t read. It can’t be built until that’s fixed.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 3
SeverityWhen
Block, also stops a test sendWhile drafting, and on a new publish.
WarningA published template whose kit or uploads changed since it was published: it still sends, using a fallback, and warns.

How to fix it

  1. Pick something that exists, such as another kit color, or add what’s missing to your brand kit or uploads.
  2. For a merge tag, fix the problem the finding names; its code is on the email format page.

render.compile: We couldn’t build the email

With the code template_too_large, the email is too big to build: its HTML, the code for its layout included, would be over the 500 KB a template can hold. With colors_too_many, it uses too many different colors: over 2,000 pairings of a color (text, border, or background) with the background behind it, each of which needs its own dark-mode color. Any other failure is on our side: it isn’t caused by anything you did, and we’ve been alerted.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 3
SeverityWhen
Our bugWhen the failure is ours.
Block, also stops a test sendWhen the email is too big to build (template_too_large).
Block, also stops a test sendWhen the email uses too many different colors (colors_too_many).

How to fix it

  1. For template_too_large, shorten or remove sections, or replace long lists with links, then try again.
  2. For colors_too_many, reuse a smaller set of text, border, and background colors. If you pasted or generated the HTML, simplify the colors in that source, then try again. A color used the same way on the same background counts once, however often it appears.
  3. For any other failure, try again. Your draft is saved.
  4. If that keeps happening, contact support with the request_id.

Gmail also cuts off emails over about 100 KB. That limit is on the finished email, and we check it once the email builds.

render.invariants: What we built broke a rule

Every email we build is checked against rules we promise: a language, alt text on images, the footer in place, no scripts, and a plain-text part with every link. One failed, which is our bug.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 5
SeverityWhen
Our bugAlways.

How to fix it

  1. Try again. Your draft is saved.
  2. If it keeps happening, contact support with the request_id.

Merge tags and Liquid

Merge tags fill in each person’s details. These checks catch tags that would fail or print nothing.

liquid.syntax: A merge tag can’t be read

A Liquid tag isn’t written correctly: a missing }} or %}, say, or a tag that’s never closed.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 3
SeverityWhen
Block, also stops a test sendWhile drafting, and on a new publish.

How to fix it

  1. Fix the tag at the finding’s line and column, or remove it.

liquid.profile: A Liquid feature we don’t support

The email uses Liquid that our templates don’t allow, such as a tag or filter outside the supported set, or a brand value your kit doesn’t have.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 5
SeverityWhen
Block, also stops a test sendAlways.
WarningA published template whose kit changed since it was published, so a brand value it names is gone: it still sends, with that value empty, and warns.

How to fix it

  1. Use a supported tag or filter, or remove it. The email format page’s Liquid section explains each rule, such as /docs/email-format#liquid-tag-unknown for a tag we don’t support.

liquid.unknown_field: A contact field that doesn’t exist

A merge tag reads a contact.* field your contacts don’t have, so it would print nothing. If one is close, we suggest it.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
WarningAlways.

How to fix it

  1. Use the suggested field, or one your contacts have.
  2. Or add the field to your contacts.

liquid.no_fallback: A merge tag with no fallback

If someone has no value for this field, nothing shows where it goes, which can leave a sentence broken.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningMarketing email.
TipTransactional email, where your app usually sends every field.

How to fix it

  1. Add a fallback: what to show when the field is empty, such as “there” in “Hi there”.

liquid.render: The email failed to build for someone

Filling in the email failed for some of the people or sample data we tried, so people with data like theirs would get nothing.

  • For: marketing, transactional email
  • Runs at: test send, publish and send, validate
  • Version: 2
SeverityWhen
Block, also stops a test sendAlways.

How to fix it

  1. Check the field the finding names, and give it a fallback or simplify the Liquid that reads it.
  2. Send a test with the same data to see it.

liquid.missing_data: A field missing from a message’s data

A transactional message’s data didn’t include a field the template reads, so that spot was left empty.

  • For: transactional email
  • Runs at: publish and send
  • Version: 2
SeverityWhen
WarningEach message sent without it. The message is still sent.

How to fix it

  1. Send every field the template reads: its meta.variables lists them.
  2. Or give the merge tag a fallback.

Size

Gmail cuts off emails over about 100 KB, hiding the end and the unsubscribe link. Sizes count the email as it will be sent, with names and tracked links filled in.

size.clip: The email is too large for Gmail

Gmail cuts off emails at about 100 KB and shows “Message clipped”, hiding the end of the email and its unsubscribe link.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 18
SeverityWhen
WarningFrom 80,000 bytes.
BlockFrom 100,000 bytes. Transactional email blocks only when a template is published; a message is never held for size.

How to fix it

  1. Remove or shorten sections. The finding lists the biggest ones.
  2. Link to long content, such as a full list, instead of including it.

size.style: Too many style rules

Gmail ignores an email’s style rules past 16 KB, which turns off phone layouts and dark-mode colors. Each custom color adds rules.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 1
SeverityWhen
WarningFrom 14,000 bytes of style rules.

How to fix it

  1. Use your brand kit’s colors instead of exact ones where you can.

size.table: A large table

One table adds a lot to the email’s size, bringing Gmail’s limit closer.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 18
SeverityWhen
TipFrom 15,000 bytes for one table.

How to fix it

  1. Link to the full list, or split it across emails.

Links that are unsafe, empty, or misleading hurt how inboxes treat your mail, and they let readers down.

Words

Your subject, preview text, and copy, checked against common problems and your brand kit’s voice.

content.subject_length: A long subject

The subject is over 60 characters. Phones cut long subjects off.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
TipOver 60 characters.

How to fix it

  1. Put the key words first, or shorten it.

content.preheader: Preview text missing, long, or repeated

Inboxes show preview text beside the subject. Without it they show the email’s first words; past about 100 characters it’s cut off; and repeating the subject wastes the space.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
TipAlways.

How to fix it

  1. Add preview text that says something the subject doesn’t, and put the key words first.

content.caps: Capitals

Capitals read as shouting, and spam filters notice them in subjects.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningA subject with 3 words in capitals in a row, or mostly capitals.
TipA paragraph that is mostly capitals.

How to fix it

  1. Write it in sentence case.

content.banned_words: A word your brand kit avoids

The email uses a word on your brand kit’s list of words to avoid.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningAlways.

How to fix it

  1. Use another word, or change the list in your brand kit.

content.preferred_words: Your brand kit spells it differently

Your brand kit prefers another spelling or word for this one.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
TipAlways.

How to fix it

  1. Use the kit’s spelling.

content.starter_text: Starter text left in

Part of the email is still the starter text it came with.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningAlways.

How to fix it

  1. Replace it with your own words, or remove it.

content.review: Text to check

Part of the email was filled in for you, by AI or from a template, and nobody has checked it yet.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningAlways.

How to fix it

  1. Read it, and change anything that isn’t right.

content.empty: An empty email

The email has nothing in it outside the footer.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
BlockAlways.

How to fix it

  1. Add a section with your message.

The law and the inbox

Marketing email must say who sent it and offer a way to unsubscribe. We add the footer that does both, and these checks make sure it’s there and readable.

compliance.identity: Your organization’s details are missing

The law requires marketing email to show who sent it: your organization’s name and postal address. We put them in your footer for you once you’ve added them. A test send shows a placeholder.

  • For: marketing email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
BlockMarketing email.

How to fix it

  1. Add your organization’s name, postal address, and contact details in your account’s settings.

compliance.unsubscribe: The unsubscribe link

Marketing email needs an unsubscribe link and a preferences link, both in the footer and in the plain-text part. We add them; if either is missing after that, it’s our bug. When the footer’s colors or size were too faint or small to read, we change them, and this says what we changed.

  • For: marketing email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 2
SeverityWhen
Our bugEither link missing from the footer or the plain text: our bug.
Added for youWe changed the footer’s colors or size so it reads.

How to fix it

  1. Nothing, if we changed it for you. To choose the change yourself, edit the footer’s colors or text size.
  2. For our bug: try again, and contact support if it keeps happening.

compliance.address: Your postal address

Marketing email must show your organization’s name and postal address, and we put them in the footer. Transactional email shows them too unless you turn them off. When transactional email’s footer colors or size were too faint or small to read, we change them, and this says what we changed.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 3
SeverityWhen
Our bugMarketing email without them after we add them: our bug.
Added for youTransactional email: we added them.
Added for youTransactional email: we changed the footer’s colors or size so it reads.

How to fix it

  1. Nothing, if they were added for you. In transactional email, you can leave them out in the footer’s settings.
  2. Nothing, if we changed the footer for you. To choose the change yourself, edit the footer’s colors or text size.

compliance.from: The sender’s name and address

The sender name includes a web or email address that isn’t the one you send from, which inboxes treat as impersonation. Or marketing email comes from a no-reply address, so readers can’t answer.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningA sender name with another address in it.
TipMarketing email from a no-reply address.

How to fix it

  1. Use your organization’s name as the sender name, and send from an address someone reads.

compliance.subject_reply: A subject that looks like a reply

The subject starts with “RE:” or “FW:” (or the same in another language), making the email look like part of a conversation. Regulators treat that as misleading.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningMarketing email.
TipTransactional email.

How to fix it

  1. Take it out of the subject.

compliance.tx_promotional: Transactional email that reads like marketing

A transactional email has offers in it, such as a discount code, a sale, or “Shop now”. Marketing needs an unsubscribe link and people’s agreement, so it can’t go out as transactional.

  • For: transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningTransactional email.

How to fix it

  1. Take the offers out, or send it as marketing email.

compliance.ai_marking: Marked as written with AI

Parts of this email were written with AI, so we mark it as AI-generated in its headers.

  • For: marketing, transactional email
  • Runs at: publish and send
  • Version: 1
SeverityWhen
Added for youAt send, when AI wrote part of the email.

How to fix it

  1. Nothing: it’s a note.

Accessibility

Everyone should be able to read your email, including people using screen readers and people on small screens. None of these stops a send.

a11y.main_heading: No single main heading

Screen readers use the main heading (level 1) to say what an email is about. An email with headings should have exactly one. An email with no headings at all, such as a letter, gets only a tip.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningHeadings, but none at level 1 or more than one.
TipNo headings at all.

How to fix it

  1. With no main heading: make the first heading level 1. The finding’s fix does it.
  2. With several: keep one at level 1 and make the rest level 2. Each finding’s fix does it for its heading.

a11y.heading_order: A heading skips a level

A heading is more than one level below the one before it, such as a level 3 right after a level 1. Screen reader users move through an email by its headings, and a gap suggests something is missing.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
TipAny skipped level, in text blocks or your own HTML.

How to fix it

  1. Change the heading to the next level down. The finding’s fix does it.

a11y.contrast: Text that’s hard to read

Text, a link, or a button label doesn’t stand out enough from what’s behind it, by the WCAG 2.2 contrast ratio in light mode. Text over a background image is checked against the section’s background color, which shows while images are off. Dark mode has its own checks.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
WarningUnder {a11y.min_contrast}:1, or {a11y.min_contrast_large}:1 for large text (24 px, or 18.66 px bold).

How to fix it

  1. Use the suggested color: the nearest one that passes. When the color is set on the element, the finding’s fix applies it.
  2. Or change the background, or pick a brand kit color with more contrast.

a11y.small_text: Small text

Body text this small is hard to read on a phone. The footer is left out: it’s small by design.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
TipUnder {a11y.min_body_px} px.

How to fix it

  1. Make the text larger. When the size is set on the element, the finding’s fix sets it to {a11y.min_body_px} px.

a11y.text_sizes: Many text sizes

The email uses a lot of different text sizes, which makes it look busy and harder to scan. Your brand kit’s sizes for headings and body text are usually enough.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
TipMore than {a11y.max_text_sizes} sizes, the footer left out.

How to fix it

  1. Use your brand kit’s sizes instead of setting one on each piece of text. The finding lists the sizes.

a11y.table_header: A table column without a header

Every table has a header row, and some of its cells are empty. On phones, each value is shown with its column’s header as a label, and so is the plain-text part, so a column without one has values with no label.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningAny empty header cell.

How to fix it

  1. Give every column a header.

a11y.lang: The language doesn’t match the text

The email’s language setting doesn’t match the language its text is in. Screen readers pronounce text by that setting, and some inboxes use it to offer a translation. We only say so when the text clearly reads as another language.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
TipThe text clearly reads as another language, or is in another script.

How to fix it

  1. Change the email’s language. When we can tell which language it is, the finding’s fix sets it.

a11y.glyphs: A font without the characters it needs

Some text is in a writing system, such as Hebrew, Arabic, or Thai, that its font has no characters for, so inboxes show that text in a different font. Another font on our list has them.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningWhen another font on our list covers the writing system. If none does, inboxes use the reader’s own.

How to fix it

  1. Change the font to the one the finding names, for this text or for the whole email.

Images

Many inboxes hide images until the reader allows them, and large files load slowly on phones. These checks look at what each image says, weighs, and needs.

img.alt_quality: An image description that doesn’t describe it

An image’s description (its alt text) is a file name, a web address, or a word like “image” or “logo” on its own. People using screen readers, and anyone with images off, get the description instead of the image.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningAny such description.

How to fix it

  1. Say what the image shows, or what it’s for, in a few words.
  2. If it’s only decoration, mark it decorative instead.

img.too_large: A large image file

A large image loads slowly on phones and mobile data, and some readers give up before it does.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
WarningOver 1,000,000 bytes.

How to fix it

  1. Use a smaller file: a JPEG for photos, saved at the size it shows at, or twice that for sharp screens.

img.total: Heavy images in total

The email’s images add up to a lot to download, which is slow on mobile data. Each file counts once.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
TipOver 3,000,000 bytes in all.

How to fix it

  1. Use fewer images, or smaller files.

img.soft: An image that may look soft

The image file isn’t much wider than the space it fills, so it may look blurry on sharp (retina) screens, which need about twice the pixels.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
TipUnder 1.5 times as wide as the space.

How to fix it

  1. Use a file about twice as wide as the space. The finding suggests a width.

img.no_width: An image in your HTML with no width

An image in your own HTML has no width in pixels. Classic Outlook then shows it at the file’s full size, which can break the layout.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
WarningAn <img> without a pixel width attribute.

How to fix it

  1. Add a width attribute in pixels. The finding suggests one when we know the file’s size.

img.format: An image format some inboxes can’t show

WebP, AVIF, HEIC, SVG, BMP, and TIFF images don’t show as they are in every inbox we test against, by caniemail.com’s data: classic Outlook can’t show WebP, AVIF, HEIC, or TIFF, and Gmail turns SVG into a flat picture. The finding names the inboxes. Uploaded images are converted for you; this is for images from other websites or your own HTML.

  • For: marketing, transactional email
  • Runs at: save, test send, publish and send, validate
  • Version: 1
SeverityWhen
WarningAny such image. While drafting it goes by the address’s file extension; at a test send and a send, by the file itself.

How to fix it

  1. Use a JPEG, PNG, or GIF, or upload the image.

img.animated: An animated image

Classic Outlook shows only the first frame of an animated GIF.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
TipAny animated image.

How to fix it

  1. Make sure the first frame says what matters on its own.

img.heavy: Mostly images

Images cover most of the email. Readers with images off see much less, and spam filters treat image-heavy mail with suspicion. Images we don’t know the size of aren’t counted.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningMarketing email whose images cover more than 0.6 of its area.
TipThe same, in transactional email.

How to fix it

  1. Move the key words out of images and into text.

img.only: Almost all images

The email has images but almost no text outside the footer. Many inboxes hide images at first, so readers see next to nothing, and spam filters distrust it.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningFewer than 100 characters of text, with at least one image.

How to fix it

  1. Add text that says what the email is about.

img.external: An image from another website

The image loads from another website, or from an address a merge tag fills in. If that site moves or removes it, it breaks in every copy of the email, even ones already sent.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
TipAny image that isn’t uploaded, except your brand kit’s logo.

How to fix it

  1. Upload a copy, so it’s served with your email.

Your own HTML

HTML you write yourself is checked when you save it, and anything unsafe is refused. These checks catch what saves but may not show as you meant, in the inboxes we test against.

html.balance: An element left open

Your HTML opens an element or a comment it never closes. We close it at the end of your HTML, so it can’t spill into the rest of the email, but the result may not be what you meant.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 1
SeverityWhen
WarningAny element or comment left open.

How to fix it

  1. Add the closing tag where it belongs. The finding points at where the element opens.

html.unsupported: HTML or CSS some inboxes don’t support

Your HTML uses an element, attribute, or CSS property that an inbox we test against doesn’t support, by caniemail.com’s data. The finding names those inboxes. What they support only partly is one tip for the whole piece of HTML.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 1
SeverityWhen
WarningNot supported in at least one inbox we test against.
TipOnly partly supported.

How to fix it

  1. Use something that works everywhere, or check the email in a test send to those inboxes.

html.width: Too wide for a phone

Part of your HTML has a fixed width a phone can’t fit, and phones can’t scroll sideways in an email.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 1
SeverityWhen
WarningWider than 600 px, or wider than 375 px with no percentage or max-width.

How to fix it

  1. Use 600 px or less with a max-width, or a percentage width.

html.hidden_text: Hidden text

Your HTML has text readers can’t see: hidden, transparent, sized to nothing, or almost the color of what’s behind it. Spam filters treat hidden text as a trick.

  • For: marketing, transactional email
  • Runs at: save, preview, publish and send, validate
  • Version: 1
SeverityWhen
WarningAny hidden text, including text under 1.5:1 against its background.

How to fix it

  1. Remove it. To set the text inboxes show beside the subject, use the preview text field.

html.layout_table_role: A table without a role

A table in your HTML has no header cells and no role="presentation", so screen readers read it cell by cell, as if it held data.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 1
SeverityWhen
TipAny such table.

How to fix it

  1. If it’s for layout, add role="presentation". If it holds data, give it header cells (<th>).

html.font: A font not on our list

Your HTML names a font that isn’t one of the fonts installed with Windows and macOS, so most readers see the next font in its list instead.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 1
SeverityWhen
TipA font list that starts with a font not on our list.

How to fix it

  1. Start the font list with a font from our list, or check that the fallback looks right.

html.color: Colors rewritten in your HTML

Your HTML wrote some colors as names, RGB or HSL values, or three-digit hex. We wrote them as six-digit hex so dark mode can adjust them; they look the same.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
Added for youWhen we rewrote at least one color.

How to fix it

  1. Nothing: it’s a note.

html.color_added: Colors added to your HTML

A link in your HTML had no color, or some text sat on a background of its own with no color. A link with no color shows each inbox’s default blue, which dark mode can’t adjust, so we gave it your email’s link color (your brand kit’s, unless the email sets its own). Text on its own background keeps the color it already had, written out so dark mode can adjust it for that background.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 1
SeverityWhen
Added for youWhen we gave at least one link or background’s text a color.

How to fix it

  1. Nothing: it’s a note. To use another color for a link, give the link a color of its own.

Dark mode

Mail apps in dark mode change your email’s colors, each in its own way, and as far as we know, leave images as they are. We predict what Apple Mail, Gmail, and Outlook do from published models, and these checks warn where light mode works and dark mode likely doesn’t. Each finding names the apps and never stops a send, and in the API its `confidence` says how sure the prediction is.

dark.text_contrast: Text that’s hard to read in dark mode

Text, a link, or a button label reaches the contrast it needs in light mode ({a11y.min_contrast}:1, or {a11y.min_contrast_large}:1 for large text), but not after a mail app’s dark mode changes its colors.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 2
SeverityWhen
WarningUnder the contrast it needs in at least one app’s dark mode.
TipOnly in the apps that use our dark-mode colors, which we’re still tuning: a note, since it isn’t yours to fix.

How to fix it

  1. Use the suggested color: the nearest one that passes in light mode and in each app we predict.
  2. Set the color for dark mode in your brand kit, for the apps that use it.

dark.image_vanishes: An image that disappears in dark mode

An image with a transparent background shows against a light background but not against the one a mail app puts behind it in dark mode, like a black logo on a dark gray page. We read it from the image’s own pixels. That analysis is coming, for uploads and, when sending, for images from other sites; until it’s in, this check finds nothing.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 2
SeverityWhen
WarningMost of the image no longer stands out from the background in at least one app.
TipAn image with a white border shows as a white box on a dark background.

How to fix it

  1. Add a light outline around the image.
  2. For your logo, add a version for dark backgrounds to your brand kit.
  3. For a white box, use an image with a transparent background.

dark.text_over_image: Text over an image in dark mode

Mail apps change the color of text but never the image behind it, so text that was readable over a picture may not be. We check it against the background color shown with images off and, once we analyze images’ pixels, against the image’s lightest or darkest part.

  • For: marketing, transactional email
  • Runs at: save, preview, test send, publish and send, validate
  • Version: 2
SeverityWhen
WarningReadable in light mode and not in at least one app’s dark mode.

How to fix it

  1. Put the text on a solid panel, which changes color with it.
  2. Move the text below the image.

dark.divider: A line that disappears in dark mode

A divider or border you can see in light mode almost disappears in dark mode. Classic Outlook darkens the background but leaves lines as they are, so a dark line vanishes there. A button’s outline needs 3:1.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 2
SeverityWhen
WarningAt least 1.5:1 in light mode and under 1.3:1 in an app’s dark mode.

How to fix it

  1. Use the suggested color.
  2. Draw the divider as a thin band of background color instead.

dark.brand_shift: A brand color that changes in dark mode

Gmail and classic Outlook change colors themselves in dark mode, and a brand color can come out as another color, like yellow turning brown. Apple Mail and Outlook.com use the dark-mode colors in your brand kit instead.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 2
SeverityWhen
WarningIt becomes another named color.
TipOnly its lightness flips, like navy turning light blue.

How to fix it

  1. Preview it in dark mode in the named apps. If you’re happy with it, leave it.
  2. For a decorative area whose color matters, an image keeps it in every app, since apps leave images as they are. Keep text off it.

dark.unmodeled: HTML we can’t predict in dark mode

Your HTML uses styles we can’t work out, such as CSS variables, calc(), or selectors our model doesn’t follow, so we can’t say what dark mode does to it.

  • For: marketing, transactional email
  • Runs at: save, preview, validate
  • Version: 2
SeverityWhen
TipAny part we can’t predict.

How to fix it

  1. Send yourself a test and open it in the named apps with dark mode on.