122

While sending email content, it is required to set "Content Transfer Encoding" header. I observed many headers of emails that I received. Some emails using "7bit" and some are using "8bit".

What is the difference between these two? Which is recommended? Is there any special encoding required for email body in order to set these headers?

mahi
  • 1,221
  • 2
  • 9
  • 3
  • I don't think it is _required_ to set this header, is it? I'm starting to work with email and I've seen emails without it - very simple, non-multipart, ASCII-text-only messages. – osullic Jun 24 '20 at 23:12

2 Answers2

362

It can be a bit dense to read, but the "Content-Transfer-Encoding" section of RFC 1341 has all of the details:

http://www.w3.org/Protocols/rfc1341/5_Content-Transfer-Encoding.html

The situation kinda goes from bad to worse. Here's my summary:

Background

SMTP, by definition (RFC 821), limits mail to lines of 1000 characters of 7 bits each. That means that none of the bytes you send down the pipe can have the most significant ("highest-order") bit set to "1".

The content that we want to send will often not obey this restriction inherently. Think of an image file, or a text file that contains Unicode characters: the bytes of these files will often have their 8th bit set to "1". SMTP doesn't allow this, so you need to use "transfer encoding" to describe how you've worked around the mismatch.

The values for the Content-Transfer-Encoding header describe the rule that you've chosen to solve this problem.

7Bit Encoding

7bit simply means "My data consists only of US-ASCII characters, which only use the lower 7 bits for each character." You're basically guaranteeing that all of the bytes in your content already adhere to the restrictions of SMTP, and so it needs no special treatment. You can just read it as-is.

Note that when you choose 7bit, you're agreeing that all of the lines in your content are less than 1000 characters in length.

As long as your content adheres to these rule, 7bit is the best transfer encoding, since there's no extra work necessary; you just read/write the bytes as they come off the pipe. It's also easy to eyeball 7bit content and make sense of it. The idea here is that if you're just writing in "plain English text" you'll be fine. But that wasn't true in 2005 and it isn't true today.

8Bit Encoding

8bit means "My data may include extended ASCII characters; they may use the 8th (highest) bit to indicate special characters outside of the standard US-ASCII 7-bit characters." As with 7bit, there's still a 1000-character line limit.

8bit, just like 7bit, does not actually do any transformation of the bytes as they're written to or read from the wire. It just means that you're not guaranteeing that none of the bytes will have the highest bit set to "1".

This seems like a step up from 7bit, since it gives you more freedom in your content. However, RFC 1341 contains this tidbit:

As of the publication of this document, there are no standardized Internet transports for which it is legitimate to include unencoded 8-bit or binary data in mail bodies. Thus there are no circumstances in which the "8bit" or "binary" Content-Transfer-Encoding is actually legal on the Internet.

RFC 1341 came out over 20 years ago. Since then we've gotten 8bit MIME Extensions in RFC 6152. But even then, line limits still may apply:

Note that this extension does NOT eliminate the possibility of an SMTP server limiting line length; servers are free to implement this extension but nevertheless set a line length limit no lower than 1000 octets.

Binary Encoding

binary is the same as 8bit, except that there's no line length restriction. You can still include any characters you want, and there's no extra encoding. Similar to 8bit, RFC 1341 states that it's not really a legitimate encoding transfer encoding. RFC 3030 extended this with BINARYMIME.

Quoted Printable

Before the 8BITMIME extension, there needed to be a way to send content that couldn't be 7bit over SMTP. HTML files (which might have more than 1000-character lines) and files with international characters are good examples of this. The quoted-printable encoding (Defined in Section 5.1 of RFC 1341) is designed to handle this. It does two things:

  • Defines how to escape non-US-ASCII characters so that they can be represented in only 7-bit characters. (Short version: they get displayed as an equals sign plus two 7-bit characters.)
  • Defines that lines will be no greater than 76 characters, and that line breaks will be represented using special characters (which are then escaped).

Quoted Printable, because of the escaping and short lines, is much harder to read by a human than 7bit or 8bit, but it does support a much wider range of possible content.

Base64 Encoding

If your data is largely non-text (ex: an image file), you don't have many options. 7bit is off the table. 8bit and binary were unsupported prior to the MIME extension RFCs. quoted-printable would work, but is really inefficient (every byte is going to be represented by 3 characters).

base64 is a good solution for this type of data. It encodes 3 raw bytes as 4 US-ASCII characters, which is relatively efficient. RFC 1341 further limits the line length of base64-encoded data to 76 characters to fit within an SMTP message, but that's relatively easy to manage when you're just splitting or concatenating arbitrary characters at fixed lengths.

The big downside is that base64-encoded data is pretty much entirely unreadable by humans, even if it's just "plain" text underneath.

Community
  • 1
  • 1
Craig Walker
  • 49,871
  • 54
  • 152
  • 212
  • 14
    This is an amazing answer, I wish I could upvote 100 times! One question though: do these rules apply for attachments? Examplle I have is an XML file attached to an email, where the contents of the XML file contain UTF-8 data. What is the right approach here? – TrojanName Jan 25 '16 at 14:06
  • 2
    @TrojanName: Yes, these apply to all email content, including attachments. (Everything isjust MIME "parts" under the covers, but that's another story.) You're still going to have to encode your content somehow to get it into an email. – Craig Walker Jan 25 '16 at 19:16
  • Right, but which to use? It's UTF-8, so can't use 7bit, but it's not a binary file (just a huge XML string), so binary and BINARYMIME probably won't work. Can you use quoted-printable on an XML file? Wouldn't that mean splitting the XML file up into chunks? This stuff is so unituitive! – TrojanName Jan 26 '16 at 00:12
  • 2
    @TrojanName: Any file is a "binary" file, regardless of whether it also can be considered text, so BINARYMIME and BINARY are available (as much as they're available for anything). 7Bit isn't good as your UTF-8 content needs 8 bits to represent content. 8Bit isn't good as it requires line length limitations that aren't part of your content. – Craig Walker Jan 26 '16 at 17:41
  • 3
    That leaves Quoted Printable or Base64, both of which can successfully encode your XML document into your email. Note that both of these are going to make it harder for a human to read in raw format (Base64 is unreadable, QP is difficult). But human readability is a secondary concern; as long as you always assume you have to decode it as well as encode it, then you're fine. – Craig Walker Jan 26 '16 at 17:43
  • @CraigWalker, Re "*base64-encoded data is pretty much entirely unreadable by humans*" is no longer such a *big* downside anymore. In fact it's a **small** downside now. Everything is base64 these days. – Pacerier Sep 05 '16 at 13:43
  • 2
    Addition restrictions: 8-bit is not supposed to include nulls or non-end-of-line CRs or LFs. – Max Oct 11 '16 at 20:54
  • 1
    Great explanation, we had an issue while sending mail with 7bit encoding where my html content crossed 1000 lines limit. Though Gmail is able to show the email properly but some other providers raised soft bounce due to encoding issue. This answer helped me fix the problem. – Vasu Ravuri Jul 23 '19 at 14:23
  • `"[...]the bytes of these files will often have their 8th bit set to "1". SMTP doesn't allow this[...]"` Does this mean that no-matter what transfer encoding is used the smtp protocol should normally(spec-wise) transfer the bytes in 7bit (8th bit being zero) unless `8BITMIME` is used? – Marinos An Apr 06 '21 at 15:48
0

With content-transfer-encoding: 7bit the bytes that are used in body (or more correct within part's boundaries) should represent ascii characters but not extended-ascii characters. This means 0-127 decimal (8th bit not used).

Since 8th bit is not used it means that you cannot encode your text using utf-8 or iso8859-7 bytes because they use the 8th bit. Nor you can add binary content.

With content-transfer-encoding: 8bit you can use any possible byte which means that you can encode your text using utf-8 bytes or iso8859-7 bytes (both assuming that 8BITMIME extension is used in SMTP). You are however still unsafe adding binary content due to the max line-restriction that still applies which could break your bytes with newlines.

Now even with 7bit content-transfer-encoding you can still set content-type's charset param to utf-8 as long as you still keep your bytes between the boundaries of 0-127.

e.g. A possible way to represent characters outside ascii using the 7bit content-transfer-encoding could be to use html code characters (with content-type: text/html)

Many email clients will set content-transfer-encoding to 7bit or 8bit depending on the case. E.g. 7bit when sending english text, 8bit when sending multilingual text. And there are always the options of quoted-printable and base64 whose characters are also not using 8th bit, but this is out of scope of the question.

Marinos An
  • 9,481
  • 6
  • 63
  • 96