RFC 2822

Internet Message Format

๐Ÿ“… published April 2001, from ietf

Internet Message Format ๐ŸŽ€

Okay bestie, let's talk about RFC 2822 ๐Ÿ’… It's dated April 2001, and it was written by P. Resnick, who edited it at QUALCOMM Incorporated. It's a Standards Track doc, which means it's an actual Internet standards track protocol, not just vibes. It obsoletes RFC 822 (the OG that this one replaces ๐Ÿ‘‘). No updates are listed for it.

Status of this Memo โœจ

This document specifies an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements. For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐Ÿ“š Distribution of this memo is unlimited ๐Ÿฆ‹

Copyright (C) The Internet Society (2001). All Rights Reserved. ๐Ÿ”’

Abstract ๐Ÿ’œ

Okay so this standard gives you a syntax for text messages that get sent between computer users, inside the whole "electronic mail" framework ๐Ÿ’Œ It supersedes the one from Request For Comments (RFC) 822, "Standard for the Format of ARPA Internet Text Messages" ๐Ÿ“ฎ It updates that older spec to match current practice and folds in the small changes that other RFCs had made along the way โœจ

Table of Contents ๐Ÿ“‘

   1. Introduction ............................................... 3
   1.1. Scope .................................................... 3
   1.2. Notational conventions ................................... 4
   1.2.1. Requirements notation .................................. 4
   1.2.2. Syntactic notation ..................................... 4
   1.3. Structure of this document ............................... 4
   2. Lexical Analysis of Messages ............................... 5
   2.1. General Description ...................................... 5
   2.1.1. Line Length Limits ..................................... 6
   2.2. Header Fields ............................................ 7
   2.2.1. Unstructured Header Field Bodies ....................... 7
   2.2.2. Structured Header Field Bodies ......................... 7
   2.2.3. Long Header Fields ..................................... 7
   2.3. Body ..................................................... 8
   3. Syntax ..................................................... 9
   3.1. Introduction ............................................. 9
   3.2. Lexical Tokens ........................................... 9
   3.2.1. Primitive Tokens ....................................... 9
   3.2.2. Quoted characters ......................................10
   3.2.3. Folding white space and comments .......................11
   3.2.4. Atom ...................................................12
   3.2.5. Quoted strings .........................................13
   3.2.6. Miscellaneous tokens ...................................13
   3.3. Date and Time Specification ..............................14
   3.4. Address Specification ....................................15
   3.4.1. Addr-spec specification ................................16
   3.5 Overall message syntax ....................................17
   3.6. Field definitions ........................................18
   3.6.1. The origination date field .............................20
   3.6.2. Originator fields ......................................21
   3.6.3. Destination address fields .............................22
   3.6.4. Identification fields ..................................23
   3.6.5. Informational fields ...................................26
   3.6.6. Resent fields ..........................................26
   3.6.7. Trace fields ...........................................28
   3.6.8. Optional fields ........................................29
   4. Obsolete Syntax ............................................29
   4.1. Miscellaneous obsolete tokens ............................30
   4.2. Obsolete folding white space .............................31
   4.3. Obsolete Date and Time ...................................31
   4.4. Obsolete Addressing ......................................33
   4.5. Obsolete header fields ...................................33
   4.5.1. Obsolete origination date field ........................34
   4.5.2. Obsolete originator fields .............................34
   4.5.3. Obsolete destination address fields ....................34
   4.5.4. Obsolete identification fields .........................35
   4.5.5. Obsolete informational fields ..........................35
   4.5.6. Obsolete resent fields .................................35
   4.5.7. Obsolete trace fields ..................................36
   4.5.8. Obsolete optional fields ...............................36
   5. Security Considerations ....................................36
   6. Bibliography ...............................................37
   7. Editor's Address ...........................................38
   8. Acknowledgements ...........................................39
   Appendix A. Example messages ..................................41
   A.1. Addressing examples ......................................41
   A.1.1. A message from one person to another with simple
          addressing .............................................41
   A.1.2. Different types of mailboxes ...........................42
   A.1.3. Group addresses ........................................43
   A.2. Reply messages ...........................................43
   A.3. Resent messages ..........................................44
   A.4. Messages with trace fields ...............................46
   A.5. White space, comments, and other oddities ................47
   A.6. Obsoleted forms ..........................................47
   A.6.1. Obsolete addressing ....................................48
   A.6.2. Obsolete dates .........................................48
   A.6.3. Obsolete white space and comments ......................48
   Appendix B. Differences from earlier standards ................49
   Appendix C. Notices ...........................................50
   Full Copyright Statement ......................................51

1. Introduction โœจ

1.1. Scope ๐Ÿ’–

This standard gives you a syntax for text messages that get sent between computer users, all within the "electronic mail" messages framework ๐Ÿ“จ It supersedes the one from Request For Comments (RFC) 822, "Standard for the Format of ARPA Internet Text Messages" [RFC822], and it updates that spec to reflect current practice. It also rolls in the incremental changes that were made in other RFCs [STD3] ๐Ÿงš

This standard only covers syntax for text messages. It makes no provision for sending images, audio, or other sorts of structured data in electronic mail messages ๐Ÿ™ˆ There are several extensions published, like the MIME document series [RFC2045, RFC2046, RFC2049], and those describe mechanisms for sending that kind of data through electronic mail. They either extend the syntax here or structure messages so they conform to this syntax. Those mechanisms are outside the scope of this standard ๐Ÿฆ‹

In the context of electronic mail, messages have an envelope and contents. The envelope holds whatever info is needed to get the message transmitted and delivered. (See [RFC2821] for a discussion of the envelope.) The contents are the object that gets delivered to the recipient. This standard applies only to the format and some of the semantics of message contents. It doesn't specify anything about the information in the envelope ๐Ÿ’Œ

However, some message systems may use information from the contents to create the envelope. This standard is meant to make it easier for programs to get that information ๐Ÿซถ

This specification defines what message content format is supposed to be passed between systems. Some message systems store messages locally in this format (which skips the need for translation between formats), and others use formats that differ from this one. Local storage is outside the scope of this standard ๐ŸŒˆ

Note: This standard isn't trying to dictate the internal formats that sites use, the specific message system features they're expected to support, or any of the characteristics of user interface programs that create or read messages. This standard also doesn't specify an encoding of the characters for transport or storage. That means it doesn't specify how many bits are used or how those bits are actually transferred over the wire or stored on disk ๐Ÿ’€

1.2. Notational conventions ๐Ÿ“

1.2.1. Requirements notation ๐Ÿ”ฅ

This document occasionally uses terms written in capital letters. When the terms "MUST", "SHOULD", "RECOMMENDED", "MUST NOT", "SHOULD NOT", and "MAY" appear capitalized, they're being used to indicate particular requirements of this specification. You can read a discussion of what these terms mean in [RFC2119] ๐Ÿ‘‘

1.2.2. Syntactic notation ๐Ÿงšโ€โ™€๏ธ

This standard uses the Augmented Backus-Naur Form (ABNF) notation specified in [RFC2234] for the formal definitions of message syntax. Characters are specified either by a decimal value (for example, the value %d65 for uppercase A and %d97 for lowercase A) or by a case-insensitive literal value wrapped in quotation marks (for example, "A" for either uppercase or lowercase A). See [RFC2234] for the full description of the notation ๐Ÿ’…

1.3. Structure of this document โœจ

okay so this doc is split into a bunch of sections, and I'm gonna walk u thru them ๐ŸŽ€

This section, section 1, is a short intro to the doc ๐ŸŒธ

Section 2 gives the general vibe of a message and its parts. It's an overview to help u get the big principles used in the later parts. Any examples in this section MUST NOT be taken as specification of the formal syntax of any part of a message. Bestie, don't treat them as the rules ๐Ÿ™…

Section 3 is where the formal ABNF rules live. It covers the structure of each part of a message (the syntax) and how those parts relate to their meaning in a message (the semantics). So it gives the actual rules for structure, plus a description of the parts and how they ought to be interpreted. It also analyzes the syntax and semantics of subparts that have specific structure. The syntax in section 3 represents messages as they MUST be created. There are also notes in section 3 that flag if any option in the syntax SHOULD be used over the others. ๐Ÿ’…

Both sections 2 and 3 describe messages that are legal to generate for purposes of this standard. ๐Ÿซถ

Section 4 specifies an "obsolete" syntax, and section 3 references those obsolete syntactic elements. The obsolete rules cover elements that showed up in earlier revisions of this standard or were widely used in Internet messages. So these elements MUST be interpreted by parsers of messages to be conformant. BUT since items in this syntax have been determined to be non-interoperable or to cause significant problems for recipients, they MUST NOT be generated by creators of conformant messages. ๐Ÿ˜ญ

Section 5 details security considerations to take into account when implementing this standard. ๐Ÿ”

Section 6 is a bibliography of the references in this document. ๐Ÿ“š

Section 7 contains the editor's address. โœ‰๏ธ

Section 8 contains acknowledgements. ๐ŸŒˆ

Appendix A lists examples of different sorts of messages. These aren't exhaustive, but they give a broad overview of certain syntactic forms. ๐Ÿงš

Appendix B lists the differences between this standard and earlier standards for Internet messages. ๐Ÿฆ‹

Appendix C has copyright and intellectual property notices. โญ


2. Lexical Analysis of Messages ๐Ÿ”

2.1. General Description

At the most basic level, a message is a series of characters. A message that's conformant with this standard is made up of characters with values in the range 1 through 127, interpreted as US-ASCII characters [ASCII]. For brevity, this document sometimes just calls this range "US-ASCII characters". ๐Ÿ’–

Note: This standard specifies that messages are made up of characters in the US-ASCII range of 1 through 127. Other documents, specifically the MIME document series [RFC2045, RFC2046, RFC2047, RFC2048, RFC2049], extend this standard to allow values outside that range. Discussing those mechanisms is outside the scope of this standard. ๐ŸŽ€

Messages are divided into lines of characters. A line is a series of characters delimited by two characters: carriage-return and line-feed. That means the carriage return (CR) character (ASCII value 13) followed immediately by the line feed (LF) character (ASCII value 10). (The carriage-return/line-feed pair is usually written in this document as CRLF.) โœจ

A message consists of header fields (collectively called "the header of the message") followed, optionally, by a body. The header is a sequence of lines of characters with special syntax as defined in this standard. The body is simply a sequence of characters that follows the header, and it's separated from the header by an empty line (i.e., a line with nothing before the CRLF). ๐ŸŒธ

2.1.1. Line Length Limits

okay so there are two limits this standard puts on the number of characters in a line. Each line of characters MUST be no more than 998 characters, and SHOULD be no more than 78 characters, excluding the CRLF. ๐Ÿ“

The 998 character limit exists because lots of implementations that send, receive, or store Internet Message Format messages simply can't handle more than 998 characters on a line. ๐Ÿ˜ฉ Receiving implementations would do well to handle an arbitrarily large number of characters in a line, for robustness. BUT there are so many implementations that (in compliance with the transport requirements of [RFC2821]) don't accept messages with more than 1000 characters per line, including the CR and LF, so it's important for implementations not to create those messages. ๐Ÿ™ˆ

The more conservative 78 character recommendation is for all the user interface implementations that display these messages. They may truncate, or disastrously wrap, anything over 78 characters per line. That's non-conformant to the intent of this specification (and that of [RFC2821] if they actually cause information to be lost), but it happens anyway. ๐Ÿ’€ Again, even though this limit is put on messages, it's incumbent upon implementations that display messages to handle an arbitrarily large number of characters in a line (certainly at least up to the 998 character limit) for the sake of robustness. ๐Ÿซถ

2.2. Header Fields

Header fields are lines made up of a field name, followed by a colon (:), followed by a field body, and terminated by CRLF. ๐Ÿ’… A field name MUST be composed of printable US-ASCII characters (i.e., characters with values between 33 and 126, inclusive), except colon. A field body may be composed of any US-ASCII characters, except for CR and LF. However, a field body may contain CRLF when used in header "folding" and "unfolding," as described in section 2.2.3. All field bodies MUST conform to the syntax described in sections 3 and 4 of this standard. ๐Ÿ”ฅ

2.2.1. Unstructured Header Field Bodies

Some field bodies in this standard are defined simply as "unstructured." That means any US-ASCII characters except CR and LF, with no further restrictions. ๐Ÿ“ These are called unstructured field bodies. Semantically, they're treated as a single line of characters with no further processing (except for header "folding" and "unfolding," as described in section 2.2.3). ๐ŸŒˆ

2.2.2. Structured Header Field Bodies

Some field bodies have a more specific syntactical structure than the unstructured ones. These are called "structured" field bodies. They're sequences of specific lexical tokens, as described in sections 3 and 4 of this standard. Lots of these tokens are allowed (according to their syntax) to be introduced or end with comments (as described in section 3.2.3). They can also have the space (SP, ASCII value 32) and horizontal tab (HTAB, ASCII value 9) characters, which together are known as the white space characters, WSP. Those WSP characters are subject to header "folding" and "unfolding," as described in section 2.2.3. Semantic analysis of structured field bodies is given along with their syntax. ๐Ÿ‘‘

2.2.3. Long Header Fields

Each header field is logically a single line of characters comprising the field name, the colon, and the field body. ๐Ÿงš For convenience, though, and to deal with the 998/78 character limits per line, the field body portion of a header field can be split into a multiple line representation. This is called "folding." The general rule is that wherever this standard allows for folding white space (not simply WSP characters), a CRLF may be inserted before any WSP. For example, the header field:

Subject: This is a test

can be represented as:

Subject: This
 is a test

Note: Even though structured field bodies are defined so folding can happen between lots of the lexical tokens (and even within some of them), folding SHOULD be limited to placing the CRLF at higher-level syntactic breaks. For instance, if a field body is defined as comma-separated values, it is recommended that folding occur after the comma separating the structured items, in preference to other places where the field could be folded, even if it's allowed elsewhere. ๐ŸŽ€

The process of moving from this folded multiple-line representation of a header field back to its single line representation is called "unfolding." ๐Ÿฆ‹ Unfolding is accomplished by simply removing any CRLF that is immediately followed by WSP. Each header field should be treated in its unfolded form for further syntactic and semantic evaluation. ๐Ÿ’œ

2.3. Body

The body of a message is simply lines of US-ASCII characters. There are only two limitations on the body:

  • CR and LF MUST only occur together as CRLF; they MUST NOT appear independently in the body.
  • Lines of characters in the body MUST be limited to 998 characters, and SHOULD be limited to 78 characters, excluding the CRLF.

Note: As we said earlier, there are other standards documents, specifically the MIME documents [RFC2045, RFC2046, RFC2048, RFC2049], that extend this standard to allow for different sorts of message bodies. Again, those mechanisms are beyond the scope of this document. ๐ŸŒธ


3. Syntax ๐Ÿ“

3.1. Introduction

The syntax in this section defines the legal syntax of Internet messages. Messages that are conformant to this standard MUST conform to the syntax in this section. If there are options in this section where one option SHOULD be generated, that's indicated either in the prose or in a comment next to the syntax. ๐Ÿ”ฅ

For the defined expressions, there's a short description of the syntax and use, followed by the syntax in ABNF, followed by a semantic analysis. Primitive tokens that are used but otherwise unspecified come from [RFC2234]. ๐Ÿ“

Some of the definitions have nonterminals whose names start with obs-. These obs- elements refer to tokens defined in the obsolete syntax in section 4. In all cases, these productions are to be ignored for the purposes of generating legal Internet messages, and they MUST NOT be used as part of such a message. ๐Ÿ™… However, when interpreting messages, these tokens MUST be honored as part of the legal syntax. So in this sense, section 3 defines a grammar for generating messages (with obs- elements that are to be ignored), while section 4 adds grammar for interpreting messages. ๐Ÿ’–

3.2. Lexical Tokens

The following rules define an underlying lexical analyzer, which feeds tokens to the higher-level parsers. This section defines the tokens used in structured header field bodies. ๐Ÿง 

Note: Readers need to pay special attention to how these lexical tokens are used in both the lower-level and higher-level syntax later in the document. In particular, the white space tokens and the comment tokens defined in section 3.2.3 get used in the lower-level tokens defined here, and those lower-level tokens are in turn used as parts of the higher-level tokens defined later. So the white space and comments may be allowed in the higher-level tokens, even if they don't explicitly appear in a particular definition. ๐Ÿซถ

3.2.1. Primitive Tokens โœจ

Okay bestie, these are the primitive tokens the rest of the standard keeps pointing back to, but they aren't defined in [RFC2234] itself ๐Ÿ’…. Some of them never show up anywhere else in the syntax, but they're still handy to have around for the rest of the doc ๐Ÿงš.

Quick note ๐Ÿซถ: specials is the perfect example. It never appears anywhere else in this standard, but it's super useful if you're building tools that lexically analyze messages ๐Ÿ”ฅ. Each character in specials can mark a tokenization point during lexical analysis.

NO-WS-CTL       =       %d1-8 /         ; US-ASCII control characters
                        %d11 /          ;  that do not include the
                        %d12 /          ;  carriage return, line feed,
                        %d14-31 /       ;  and white space characters
                        %d127

text            =       %d1-9 /         ; Characters excluding CR and LF
                        %d11 /
                        %d12 /
                        %d14-127 /
                        obs-text

specials        =       "(" / ")" /     ; Special characters used in
                        "<" / ">" /     ;  other parts of the syntax
                        "[" / "]" /
                        ":" / ";" /
                        "@" / "\" /
                        "," / "." /
                        DQUOTE

These specials have no special semantics attached to them. They're just single characters, period ๐ŸŒธ.

3.2.2. Quoted characters โœจ

Some characters are reserved for special interpretation, like delimiting lexical tokens ๐Ÿ’–. So if you want to use them as plain uninterpreted data, there's a quoting mechanism for that ๐ŸŽ€.

quoted-pair     =       ("\" text) / obs-qp

Wherever a quoted-pair shows up, it gets interpreted as the text character all by itself. The "\" inside a quoted-pair is semantically "invisible" ๐Ÿ™ˆ.

Note ๐Ÿ’€: the "\" character can appear in a message without being part of a quoted-pair. A "\" that isn't inside a quoted-pair is not semantically invisible. The only places in this standard where quoted-pair currently appears are ccontent, qcontent, dcontent, no-fold-quote, and no-fold-literal.

3.2.3. Folding white space and comments โœจ

White space characters, including the ones used in folding (see section 2.2.3), can show up between a bunch of elements in header field bodies ๐Ÿฆ‹. Strings wrapped in parentheses can also act as comments inside structured field bodies. Here's how the folding white space (FWS) and comment constructs are defined ๐Ÿ’….

Strings of characters enclosed in parentheses count as comments, as long as they don't appear within a "quoted-string" (see section 3.2.5). Comments are allowed to nest ๐Ÿช†.

There are a bunch of spots in this standard where comments and FWS can be freely tucked in. To cover that, there's an extra token called "CFWS" for anywhere comments and/or FWS can occur. Just know that wherever CFWS shows up in this standard, it MUST NOT be inserted in such a way that any line of a folded header field is made up entirely of WSP characters and nothing else ๐Ÿšซ.

FWS             =       ([*WSP CRLF] 1*WSP) /   ; Folding white space
                        obs-FWS

ctext           =       NO-WS-CTL /     ; Non white space controls

                        %d33-39 /       ; The rest of the US-ASCII
                        %d42-91 /       ;  characters not including "(",
                        %d93-126        ;  ")", or "\"

ccontent        =       ctext / quoted-pair / comment

comment         =       "(" *([FWS] ccontent) [FWS] ")"

CFWS            =       *([FWS] comment) (([FWS] comment) / FWS)

Anywhere FWS (the folding white space token) shows up, it's marking a spot where header folding (covered in section 2.2.3) can happen ๐ŸŽ€. Whenever a message has header folding (a header field body with a CRLF followed by any WSP), header unfolding (removing that CRLF) happens before any more lexical analysis of that header field under this standard. So any CRLF inside an FWS is semantically "invisible" ๐Ÿ™ˆ.

Comments are usually used in structured field bodies to hold some human-readable info ๐ŸŒˆ. Since a comment is allowed to have FWS, folding can happen inside it too. Also, because quoted-pair is allowed in a comment, parentheses and backslashes can show up in there as long as they're written as a quoted-pair โœจ. The enclosing parentheses aren't actually part of the comment. The comment is just whatever sits between them. Like we said earlier, the "\" in any quoted-pair and the CRLF in any FWS inside the comment are semantically "invisible," so they aren't part of the comment either ๐Ÿซถ.

Runs of FWS, comment, or CFWS that sit between lexical tokens in a structured field header get interpreted as one single space character ๐ŸŒธ.

3.2.4. Atom โœจ

A bunch of productions in structured header field bodies are just strings made of certain basic characters. Those productions are called atoms ๐Ÿ“.

Some structured header field bodies also let you use the period character (".", ASCII value 46) inside runs of atext. There's an extra token called "dot-atom" for exactly that ๐Ÿงš.

atext           =       ALPHA / DIGIT / ; Any character except controls,
                        "!" / "#" /     ;  SP, and specials.
                        "$" / "%" /     ;  Used for atoms
                        "&" / "'" /
                        "*" / "+" /
                        "-" / "/" /
                        "=" / "?" /
                        "^" / "_" /
                        "`" / "{" /
                        "|" / "}" /
                        "~"

atom            =       [CFWS] 1*atext [CFWS]

dot-atom        =       [CFWS] dot-atom-text [CFWS]

dot-atom-text   =       1*atext *("." 1*atext)

Both atom and dot-atom get treated as a single unit, made up of the characters they contain ๐Ÿ’–. The optional comments and FWS around them aren't part of the atom. The atom is only the run of atext characters, or the atext and "." characters for a dot-atom โœจ.

3.2.5. Quoted strings โœจ

Strings with characters that aren't allowed in atoms can be written in quoted string format, where the characters are wrapped in quote characters (DQUOTE, ASCII value 34) ๐ŸŽ€.

qtext           =       NO-WS-CTL /     ; Non white space controls

                        %d33 /          ; The rest of the US-ASCII
                        %d35-91 /       ;  characters not including "\"
                        %d93-126        ;  or the quote character

qcontent        =       qtext / quoted-pair

quoted-string   =       [CFWS]
                        DQUOTE *([FWS] qcontent) [FWS] DQUOTE
                        [CFWS]

A quoted-string gets treated as one unit. Semantically, a quoted-string is identical to an atom ๐Ÿ’…. Since it's allowed to have FWS, folding is permitted inside it too. And because quoted-pair is allowed in a quoted-string, the quote and backslash characters can appear in there as long as they're written as a quoted-pair ๐ŸŒˆ.

Semantically, the optional CFWS outside the quote characters isn't part of the quoted-string, and neither are the quote characters themselves. The quoted-string is just what sits between the two quote characters ๐Ÿซถ. Like before, the "\" in any quoted-pair and the CRLF in any FWS/CFWS inside the quoted-string are semantically "invisible," so they aren't part of the quoted-string either ๐Ÿ™ˆ.

3.2.6. Miscellaneous tokens โœจ

Three more tokens get defined here. word and phrase cover combinations of atoms and/or quoted-strings, and unstructured is for unstructured header fields and some spots inside structured header fields ๐Ÿฆ‹.

word            =       atom / quoted-string

phrase          =       1*word / obs-phrase
utext           =       NO-WS-CTL /     ; Non white space controls
                        %d33-126 /      ; The rest of US-ASCII
                        obs-utext

unstructured    =       *([FWS] utext) [FWS]

3.3. Date and Time Specification โœจ

Date and time show up in several header fields ๐Ÿ•ฐ๏ธ. This section lays out the syntax for a full date and time specification. Folding white space is allowed all over the date-time specification, but it is RECOMMENDED that a single space be used everywhere FWS appears (whether it's required or optional). Some older implementations might not interpret other folding white space occurrences correctly ๐Ÿ’€.

date-time       =       [ day-of-week "," ] date FWS time [CFWS]

day-of-week     =       ([FWS] day-name) / obs-day-of-week

day-name        =       "Mon" / "Tue" / "Wed" / "Thu" /
                        "Fri" / "Sat" / "Sun"

date            =       day month year

year            =       4*DIGIT / obs-year

month           =       (FWS month-name FWS) / obs-month

month-name      =       "Jan" / "Feb" / "Mar" / "Apr" /
                        "May" / "Jun" / "Jul" / "Aug" /
                        "Sep" / "Oct" / "Nov" / "Dec"

day             =       ([FWS] 1*2DIGIT) / obs-day

time            =       time-of-day FWS zone

time-of-day     =       hour ":" minute [ ":" second ]

hour            =       2DIGIT / obs-hour

minute          =       2DIGIT / obs-minute

second          =       2DIGIT / obs-second

zone            =       (( "+" / "-" ) 4DIGIT) / obs-zone

The day is the numeric day of the month ๐Ÿ“…. The year is any numeric year from 1900 onward ๐ŸŽ‚.

The time-of-day tells you how many hours, minutes, and optionally seconds have passed since midnight on the date given โฐ.

The date and time-of-day SHOULD express local time ๐ŸŒ.

The zone is the offset from Coordinated Universal Time (UTC, formerly known as "Greenwich Mean Time") that the date and time-of-day represent ๐ŸŒ. A "+" or "-" shows whether the time-of-day is ahead of (east of) or behind (west of) Universal Time. The first two digits are the number of hours difference from Universal Time, and the last two digits are the number of minutes difference from Universal Time. (So +hhmm means +(hh * 60 + mm) minutes, and -hhmm means -(hh * 60 + mm) minutes ๐Ÿงฎ.) The form "+0000" SHOULD be used to indicate a time zone at Universal Time โœจ. "-0000" also means Universal Time, but it's used to say the time was generated on a system that might be in a local time zone other than Universal Time. So it signals that the date-time has no information about the local time zone ๐Ÿ™ˆ.

A date-time specification MUST be semantically valid ๐Ÿ’–. That means the day-of-the-week (if included) MUST be the day implied by the date, the numeric day-of-month MUST be between 1 and the number of days allowed for the specified month (in the specified year), the time-of-day MUST be in the range 00:00:00 through 23:59:60 (the number of seconds allowing for a leap second; see [STD12]), and the zone MUST be within the range -9959 through +9959 ๐Ÿ”ฅ.

3.4. Address Specification ๐Ÿ’Œ

Okay bestie, addresses are how messages know who's sending and who's getting them ๐Ÿ’– They show up in a bunch of header fields. An address is either one individual mailbox or a whole group of mailboxes โœจ

address         =       mailbox / group

mailbox         =       name-addr / addr-spec

name-addr       =       [display-name] angle-addr

angle-addr      =       [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr

group           =       display-name ":" [mailbox-list / CFWS] ";"
                        [CFWS]

display-name    =       phrase

mailbox-list    =       (mailbox *("," mailbox)) / obs-mbox-list

address-list    =       (address *("," address)) / obs-addr-list

A mailbox is the thing that receives mail ๐Ÿ“ฌ It's a conceptual entity, so it doesn't have to be a file sitting somewhere on a disk. For example, some sites might print mail out and deliver the printout to the addressee's desk ๐Ÿ–จ๏ธ Normally a mailbox has two parts: (1) an optional display name, which is the name of the recipient (it could be a person or a system) that a mail app can show to the user, and (2) an addr-spec address wrapped in angle brackets ("<" and ">"). There's also a simple alternate form where the addr-spec shows up all alone, without a name or the angle brackets. The Internet addr-spec address is described in section 3.4.1 ๐Ÿ”

Note: Some legacy implementations used the simple form, with the addr-spec appearing without angle brackets, but they put the recipient's name in parentheses as a comment after the addr-spec. Since the meaning of a comment is unspecified, implementations SHOULD use the full name-addr form of the mailbox instead of the legacy form to specify the display name for a mailbox. Also, because some legacy implementations interpret the comment, comments generally SHOULD NOT be used in address fields so those implementations don't get confused ๐Ÿ™ˆ

When you want to treat several mailboxes as one unit (like a distribution list ๐Ÿ“ฃ), that's where the group construct comes in. It lets the sender name a group of recipients. You give the group a display name, then a colon, then a comma separated list of any number of mailboxes (including zero and one), and you end with a semicolon. Because the list of mailboxes can be empty, the group construct is also a simple way to tell recipients that the message went to one or more named sets of people, without actually giving the individual mailbox address for each of them ๐Ÿซถ

3.4.1. Addr-spec specification ๐Ÿ”

An addr-spec is a specific Internet identifier. It has a locally interpreted string, then the at-sign character ("@", ASCII value 64), then an Internet domain ๐ŸŒ The locally interpreted string is either a quoted-string or a dot-atom. If the string can be written as a dot-atom (meaning it has no characters other than atext characters, or "." surrounded by atext characters), then the dot-atom form SHOULD be used and the quoted-string form SHOULD NOT be used. Comments and folding white space SHOULD NOT be used around the "@" in the addr-spec ๐Ÿ’…

addr-spec       =       local-part "@" domain

local-part      =       dot-atom / quoted-string / obs-local-part

domain          =       dot-atom / domain-literal / obs-domain

domain-literal  =       [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]

dcontent        =       dtext / quoted-pair

dtext           =       NO-WS-CTL /     ; Non white space controls

                        %d33-90 /       ; The rest of the US-ASCII
                        %d94-126        ;  characters not including "[",
                                        ;  "]", or "\"

The domain part is the point the mail gets delivered to ๐ŸŽฏ In the dot-atom form, it's read as an Internet domain name (either a host name or a mail exchanger name) as described in [STD3, STD13, STD14]. In the domain-literal form, the domain is read as the literal Internet address of the particular host. In both cases, how addressing works and how messages get transported to a particular host is covered in the mail transport document [RFC2821]. Those mechanisms are outside the scope of this document, so we're not going there today ๐Ÿ™…โ€โ™€๏ธ

The local-part is a domain dependent string. In addresses, it's simply interpreted on the particular host as the name of a particular mailbox ๐Ÿฆ‹

3.5 Overall message syntax โœ‰๏ธ

A message is made of header fields, optionally followed by a message body ๐Ÿ’Œ Lines in a message MUST be a maximum of 998 characters excluding the CRLF, but it is RECOMMENDED that lines be limited to 78 characters excluding the CRLF. (See section 2.1.1 for explanation.) In a message body, all of the characters listed in the text rule MAY be used, though the use of US-ASCII control characters (values 1 through 8, 11, 12, and 14 through 31) is discouraged, since their interpretation by receivers for display is not guaranteed ๐Ÿ™ˆ

message         =       (fields / obs-fields)
                        [CRLF body]

body            =       *(*998text CRLF) *998text

The header fields carry most of the semantic information, and they're defined in section 3.6 ๐Ÿง  The body is just a series of lines of text, and for the purposes of this standard they're uninterpreted, so nothing gets read into them ๐ŸŒธ

3.6. Field definitions ๐Ÿ“‹

All the header fields of a message are defined here โœจ Every header field has the same general structure: a field name, then a colon, then the field body. The specific syntax for each header field is defined in the subsequent sections.

Note: In the ABNF syntax for each field in the subsequent sections, each field name is followed by the required colon. For brevity, though, the colon sometimes isn't mentioned in the textual description of the syntax. It is, nonetheless, required.

It's important to know that header fields are NOT guaranteed to be in any particular order ๐ŸŒ€ They may appear in any order, and they've been known to get reordered now and then when they travel over the Internet. However, for the purposes of this standard, header fields SHOULD NOT be reordered when a message is transported or transformed. Even more important, the trace header fields and resent header fields MUST NOT be reordered, and they SHOULD be kept in blocks prepended to the message. See sections 3.6.6 and 3.6.7 for more information ๐Ÿ‘‘

The only required header fields are the origination date field and the originator address field(s). Every other header field is syntactically optional. More information is in the table after this definition ๐Ÿ’–

fields          =       *(trace
                          *(resent-date /
                           resent-from /
                           resent-sender /
                           resent-to /
                           resent-cc /
                           resent-bcc /
                           resent-msg-id))
                        *(orig-date /
                        from /
                        sender /
                        reply-to /
                        to /
                        cc /
                        bcc /
                        message-id /
                        in-reply-to /
                        references /
                        subject /
                        comments /
                        keywords /
                        optional-field)

This table shows the limits on how many times each field can occur in a message header, plus any special rules for using those fields ๐Ÿ“Š An asterisk next to a value in the minimum or maximum column means there's a special restriction in the Notes column ๐Ÿ”ฅ

Field           Min number      Max number      Notes

trace           0               unlimited       Block prepended - see
                                                3.6.7

resent-date     0*              unlimited*      One per block, required
                                                if other resent fields
                                                present - see 3.6.6

resent-from     0               unlimited*      One per block - see
                                                3.6.6

resent-sender   0*              unlimited*      One per block, MUST
                                                occur with multi-address
                                                resent-from - see 3.6.6

resent-to       0               unlimited*      One per block - see
                                                3.6.6

resent-cc       0               unlimited*      One per block - see
                                                3.6.6

resent-bcc      0               unlimited*      One per block - see
                                                3.6.6

resent-msg-id   0               unlimited*      One per block - see
                                                3.6.6

orig-date       1               1

from            1               1               See sender and 3.6.2
sender          0*              1               MUST occur with multi-
                                                address from - see 3.6.2

reply-to        0               1

to              0               1

cc              0               1

bcc             0               1

message-id      0*              1               SHOULD be present - see
                                                3.6.4

in-reply-to     0*              1               SHOULD occur in some
                                                replies - see 3.6.4

references      0*              1               SHOULD occur in some
                                                replies - see 3.6.4

subject         0               1

comments        0               unlimited

keywords        0               unlimited

optional-field  0               unlimited

The exact interpretation of each field is described in the subsequent sections ๐Ÿ”

3.6.1. The origination date field ๐Ÿ“…

The origination date field is made of the field name "Date" followed by a date-time specification ๐Ÿ—“๏ธ

orig-date       =       "Date:" date-time CRLF

The origination date tells you the date and time when the message's creator said it was complete and ready to enter the mail delivery system. For instance, that might be the moment someone hits the "send" or "submit" button in an app ๐Ÿš€ Either way, it is specifically NOT meant to show when the message actually got transported. It's about when the human (or other creator) put the message into its final form, ready to go. (For example, a portable computer user who isn't connected to a network might queue a message for delivery. The origination date is meant to hold the date and time the user queued the message, not the time they connected to the network to send it ๐Ÿ’ปโœจ)

3.6.2. Originator fields โœจ

okay so the originator fields are the "who sent this and who do I reply to" crew ๐Ÿซถ there's the from field, which is "From:" followed by a comma-separated list of one or more mailbox specifications. If the from field has more than one mailbox specification in the mailbox-list, then a sender field (the name "Sender:" plus a single mailbox specification) MUST appear in the message ๐Ÿ”ฅ either way, an optional reply-to field MAY also be included, with the name "Reply-To:" and a comma-separated list of one or more addresses ๐Ÿ’–

from            =       "From:" mailbox-list CRLF

sender          =       "Sender:" mailbox CRLF

reply-to        =       "Reply-To:" address-list CRLF

the originator fields tell everyone which mailbox(es) the message came from ๐Ÿ“ฌ the "From:" field names the author(s), meaning the mailbox(es) of the person or system responsible for writing the message ๐Ÿงš the "Sender:" field names the mailbox of the agent responsible for actually sending it ๐Ÿ’… for example, if a secretary sends a message for her boss, the secretary's mailbox goes in the "Sender:" field and the boss's mailbox goes in the "From:" field ๐Ÿ™ˆ if one mailbox can cover the author and the transmitter and they're the same person, the "Sender:" field SHOULD NOT be used ๐Ÿ’€ otherwise, both fields SHOULD appear ๐ŸŒธ

the originator fields also carry the info you need for replies ๐Ÿฆ‹ when "Reply-To:" is there, it shows the mailbox(es) the author would like replies sent to โœจ without a "Reply-To:" field, replies SHOULD by default go to the mailbox(es) in the "From:" field, unless the person writing the reply says otherwise ๐Ÿ’œ

and one more thing: the "From:" field SHOULD NOT contain any mailbox that doesn't belong to the author(s) of the message ๐ŸŽ€ for more on working out reply destinations, see section 3.6.3 ๐Ÿ‘‘

3.6.3. Destination address fields ๐ŸŽ€

the destination fields are three possible fields that all have the same shape ๐ŸŒˆ the field name is "To", "Cc", or "Bcc", followed by a comma-separated list of one or more addresses (mailbox syntax or group syntax) ๐Ÿ’–

to              =       "To:" address-list CRLF

cc              =       "Cc:" address-list CRLF

bcc             =       "Bcc:" (address-list / [CFWS]) CRLF

these fields tell you who the recipients are ๐Ÿฆ‹ each destination field can hold one or more addresses, and each address is an intended recipient โœจ the only real difference between the three is how each one gets used ๐Ÿ’…

the "To:" field holds the address(es) of the primary recipient(s) ๐Ÿ‘‘

the "Cc:" field (Cc stands for "Carbon Copy", like making a copy on a typewriter with carbon paper) holds addresses of others who should get the message, even if the content isn't really aimed at them ๐Ÿซถ

the "Bcc:" field (Bcc stands for "Blind Carbon Copy") holds addresses of recipients whose addresses must not be shown to the other recipients ๐Ÿ™ˆ there are three ways this plays out ๐Ÿ”ฅ in the first, when a message with a "Bcc:" field is getting ready to send, the "Bcc:" line gets removed, even though everyone listed in it (including those in the "Bcc:" field) still gets a copy ๐Ÿ’€ in the second, the recipients in "To:" and "Cc:" each get a copy with the "Bcc:" line removed, but the people on the "Bcc:" line get their own separate copy that still has a "Bcc:" line ๐Ÿ˜ญ (when there are several addresses in the "Bcc:" field, some implementations actually send each recipient their own copy, with a "Bcc:" line that only has that one person's address ๐Ÿงš) finally, since a "Bcc:" field may have no addresses at all, it can be sent empty to tell recipients that blind copies went out to someone ๐ŸŒธ which method to use with "Bcc:" fields is up to the implementation, but check the "Security Considerations" section of this document for a breakdown of each ๐Ÿ”ฅ

when a message is a reply, the mailboxes of the original authors (the ones in the "From:" field), or the ones in the "Reply-To:" field if it exists, MAY appear in the "To:" field of the reply ๐Ÿ’– those are normally the main people you're replying to, so it makes sense ๐Ÿ’… if the original message had destination fields, it's often nice to send a copy of the reply to all of those recipients too, along with the author โœจ when that happens, addresses from the original "To:" and "Cc:" fields MAY appear in the reply's "Cc:" field, since they're usually secondary recipients of the reply ๐Ÿฆ‹ if the original message had a "Bcc:" field, its addresses MAY appear in the reply's "Bcc:" field, but they SHOULD NOT appear in the reply's "To:" or "Cc:" fields ๐Ÿ™ˆ

Note: some mail apps have automatic reply commands that copy the original message's destination addresses into the reply's destination addresses ๐ŸŽ€ how those commands behave is up to the implementation and outside the scope of this document ๐Ÿ’€ in particular, whether to include the original destination addresses when the original message had a "Reply-To:" field isn't covered here ๐Ÿ˜ญ

3.6.4. Identification fields ๐Ÿชช

Okay bestie, these are the ID fields ๐Ÿ†” Though optional, every message SHOULD have a Message-ID: field. Reply messages SHOULD also have In-Reply-To: and References: fields as appropriate, as described below. ๐Ÿ’–

The Message-ID: field holds a single unique message identifier. The References: and In-Reply-To: fields each hold one or more unique message identifiers, optionally separated by CFWS. โœจ

The message identifier (msg-id) is kinda like an angle-addr construct, just without the internal CFWS ๐Ÿ’…

message-id      =       "Message-ID:" msg-id CRLF

in-reply-to     =       "In-Reply-To:" 1*msg-id CRLF

references      =       "References:" 1*msg-id CRLF

msg-id          =       [CFWS] "<" id-left "@" id-right ">" [CFWS]

id-left         =       dot-atom-text / no-fold-quote / obs-id-left

id-right        =       dot-atom-text / no-fold-literal / obs-id-right

no-fold-quote   =       DQUOTE *(qtext / quoted-pair) DQUOTE
no-fold-literal =       "[" *(dtext / quoted-pair) "]"

The Message-ID: field gives a unique ID to one particular version of one particular message ๐Ÿฆ‹ Uniqueness is guaranteed by the host that generates it (more on that below). The ID is meant for machines to read, and isn't necessarily meaningful to humans ๐Ÿค– Each message identifier belongs to exactly one instantiation of a message, so every later revision gets a brand new one. ๐ŸŒธ

Note: Lots of messages get "changed" without becoming a new message, and those changes don't earn a new message identifier. For example, when messages enter the transport system they're often prepended with extra header fields like trace fields (described in section 3.6.7) and resent fields (described in section 3.6.6). Adding those fields doesn't change the message's identity, so the original Message-ID: field stays put. In every case, what decides whether Message-ID: changes is the meaning the sender wants to convey (is this the same message or a different one?), not any particular syntactic difference that shows up in the message (or doesn't). ๐Ÿง 

The In-Reply-To: and References: fields are used when you're creating a reply to a message ๐Ÿ’Œ They hold the message identifier of the original message, plus the identifiers of other messages (say, if you're replying to a message that was itself a reply). In-Reply-To: can point to the message (or messages) that the new one is replying to, while References: can be used to track a "thread" of conversation ๐Ÿงต

When you create a reply, the In-Reply-To: and References: fields of the resulting message get built like this:

The In-Reply-To: field will contain the contents of the Message-ID: field of the message this one is replying to (the "parent message"). If there's more than one parent message, In-Reply-To: will contain the contents of all of the parents' Message-ID: fields. If none of the parent messages has a Message-ID: field, the new message gets no In-Reply-To: field at all. ๐Ÿ™ƒ

The References: field will contain the contents of the parent's References: field (if it has one), followed by the contents of the parent's Message-ID: field (if it has one). If the parent doesn't have a References: field but does have an In-Reply-To: field containing a single message identifier, then References: will contain the contents of the parent's In-Reply-To: field, followed by the contents of the parent's Message-ID: field (if it has one). If the parent has none of the References:, In-Reply-To:, or Message-ID: fields, the new message gets no References: field. ๐ŸŒˆ

Note: Some implementations parse the References: field to show the "thread of the discussion." Those implementations assume each new message replies to a single parent, so they can walk backwards through References: to find each message's parent. That's why building a References: field for a reply with multiple parents is discouraged, and this document doesn't define how to do it. ๐Ÿ™ˆ

The message identifier (msg-id) itself MUST be a globally unique identifier for a message ๐Ÿ”‘ The generator of the message identifier MUST guarantee that the msg-id is unique. There are several algorithms that can do this. Since msg-id is syntactically similar to angle-addr (identical, except that comments and folding white space aren't allowed), a good method is to put the domain name (or a domain literal IP address) of the host where the identifier was created on the right-hand side of the "@". On the left-hand side, put a combination of the current absolute date and time, plus some other currently unique (perhaps sequential) identifier available on the system (for example, a process ID number) โฐ Using a date on the left and a domain name or domain literal on the right makes uniqueness guaranteeable, since no two hosts use the same domain name or IP address at the same time. Other algorithms will work too, but it is RECOMMENDED that the right-hand side contain some domain identifier (either of the host itself or of something else) so the generator can guarantee the left-hand side is unique within that domain's scope. ๐Ÿ‘‘

Semantically speaking, the angle bracket characters aren't part of the msg-id. The msg-id is just whatever sits between the two angle brackets ๐Ÿฅฐ

3.6.5. Informational fields ๐Ÿ’Œ

All of the informational fields are optional ๐ŸŽ€ The Keywords: field contains a comma-separated list of one or more words or quoted-strings. The Subject: and Comments: fields are unstructured fields as defined in section 2.2.1, so they can contain text or folding white space ๐Ÿ“

subject         =       "Subject:" unstructured CRLF

comments        =       "Comments:" unstructured CRLF

keywords        =       "Keywords:" phrase *("," phrase) CRLF

These three fields are meant to hold only human-readable info about the message ๐Ÿ‘€ Subject: is the most common one, and holds a short string naming the topic of the message. When used in a reply, the field body MAY start with the string Re: (from the Latin "res," meaning "in the matter of") followed by the contents of the original message's Subject: field body ๐ŸŒท If you do this, only one instance of the literal string Re: ought to be used, because using other strings, or more than one instance, can lead to undesirable consequences ๐Ÿ˜ฌ Comments: holds any extra notes about the body of the message. Keywords: holds a comma-separated list of important words and phrases that might be useful to the recipient ๐Ÿ”

3.6.6. Resent fields ๐Ÿ”

Resent fields SHOULD be added to any message that a user reintroduces into the transport system ๐Ÿš€ A separate set of resent fields SHOULD be added each time that happens. All of the resent fields for a particular resending SHOULD be kept together. Each new set of resent fields gets prepended to the message, so the most recent set appears earliest in the message. No other fields in the message change when resent fields are added. ๐Ÿซถ

Each resent field matches a particular field elsewhere in the syntax. For instance, Resent-Date: corresponds to Date:, and Resent-To: corresponds to To:. In each case, the syntax for the field body is identical to the syntax given earlier for the corresponding field ๐Ÿ“‹

When resent fields are used, the Resent-From: and Resent-Date: fields MUST be sent. The Resent-Message-ID: field SHOULD be sent. Resent-Sender: SHOULD NOT be used if Resent-Sender: would be identical to Resent-From: ๐Ÿ™…โ€โ™€๏ธ

resent-date     =       "Resent-Date:" date-time CRLF

resent-from     =       "Resent-From:" mailbox-list CRLF

resent-sender   =       "Resent-Sender:" mailbox CRLF

resent-to       =       "Resent-To:" address-list CRLF

resent-cc       =       "Resent-Cc:" address-list CRLF

resent-bcc      =       "Resent-Bcc:" (address-list / [CFWS]) CRLF

resent-msg-id   =       "Resent-Message-ID:" msg-id CRLF

Resent fields are how a message shows it's been reintroduced into the transport system by a user ๐Ÿ’… The whole point is that the message looks to the final recipient as if the original sender sent it directly, with all of the original fields staying the same โœจ Each set of resent fields matches one resending event. So if a message gets resent several times, each set gives identifying info for that one time. Resent fields are strictly informational, which means they MUST NOT be used in the normal processing of replies or other automatic actions on messages ๐Ÿ›‘

Note: Reintroducing a message and using resent fields is a different operation from "forwarding," and forwarding has two meanings ๐Ÿ’โ€โ™€๏ธ In the first sense, a mail reading program can be told by a user to forward a copy of a message to someone else, making the forwarded message the body of a new message. That forwarded message doesn't look like it came from the original sender. It's a totally new message from the forwarder. In the second sense, a mail transport program gets a message and forwards it on to a different destination for final delivery. Resent header fields aren't meant for either kind of forwarding. ๐ŸŒธ

The resent originator fields show the mailbox of the person(s) or system(s) that resent the message ๐Ÿ“ฎ Just like the regular originator fields, there are two forms. There's the simple Resent-From: form, which holds the mailbox of the individual doing the resending. And there's the fancier form, used when one individual (named in the Resent-Sender: field) resends a message on behalf of one or more others (named in the Resent-From: field) ๐Ÿงš

Note: When you reply to a resent message, replies work exactly like they would for any other message, using the original From:, Reply-To:, Message-ID:, and other fields. The resent fields are only informational and MUST NOT be used in the normal processing of replies ๐Ÿ™Œ

Resent-Date: shows the date and time when the resender dispatched the resent message. Like Date:, it isn't the date and time the message was actually transported โฐ

Resent-To:, Resent-Cc:, and Resent-Bcc: work exactly like To:, Cc:, and Bcc:, except they list the recipients of the resent message instead of the recipients of the original message ๐Ÿ’œ

Resent-Message-ID: gives a unique identifier for the resent message ๐Ÿฆ‹

3.6.7. Trace fields ๐Ÿฆ‹

okay so trace fields are a group of header fields made of an optional "Return-Path:" field and one or more "Received:" fields ๐Ÿ’Œ. "Return-Path:" has a pair of angle brackets wrapping an optional addr-spec. "Received:" holds a possibly empty list of name/value pairs, then a semicolon, then a date-time specification. The first item in each pair is an item-name, and the second is an addr-spec, an atom, a domain, or a msg-id โœจ. Standards that provide for trace fields can add further restrictions to their syntax, like [RFC2821] does ๐Ÿงš

trace           =       [return]
                        1*received

return          =       "Return-Path:" path CRLF

path            =       ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
                        obs-path

received        =       "Received:" name-val-list ";" date-time CRLF

name-val-list   =       [CFWS] [name-val-pair *(CFWS name-val-pair)]

name-val-pair   =       item-name CFWS item-value

item-name       =       ALPHA *(["-"] (ALPHA / DIGIT))

item-value      =       1*angle-addr / addr-spec /
                         atom / domain / msg-id

The whole deep dive on how trace fields get used in Internet mail lives in [RFC2821] ๐Ÿ“ฌ. For this standard though, trace fields are strictly informational, and any formal interpretation of them is outside the scope of this document ๐Ÿซถ

3.6.8. Optional fields ๐ŸŽ€

Fields can show up in messages that this standard doesn't specify otherwise ๐ŸŒธ. They MUST conform to the syntax of an optional-field. Basically it's a field name made of printable US-ASCII characters (except SP and colon), then a colon, then any text that follows unstructured ๐Ÿ’…

The field names of any optional-field MUST NOT be identical to any field name specified elsewhere in this standard ๐Ÿ™ˆ

optional-field  =       field-name ":" unstructured CRLF

field-name      =       1*ftext

ftext           =       %d33-57 /               ; Any character except
                        %d59-126                ;  controls, SP, and
                                                ;  ":".

For this standard, any optional field is uninterpreted ๐Ÿ“


4. Obsolete Syntax โœจ

Earlier versions of this standard allowed different syntax, usually more liberal than what this version allows ๐Ÿ•ฐ๏ธ. Also, plenty of syntactic elements have shown up in Internet messages over the years whose meaning was never documented ๐Ÿ’€. Some of these syntactic forms MUST NOT be generated according to the grammar in section 3, but they MUST be accepted and parsed by a conformant receiver ๐Ÿซถ. This section documents many of these elements. Take the grammar in section 3, add the definitions from this section, and you get the grammar to use for interpreting messages ๐Ÿ”ฅ

Note: This section identifies syntactic forms that any implementation MUST reasonably interpret. There are definitely Internet messages that don't conform even to the extra syntax in this section, though. The fact that a form doesn't appear in any section of this document is no excuse for programs to crash, or for malformed data to be irretrievably lost by any implementation ๐Ÿ˜ญ. Like, this document requires lines in messages to be no longer than 998 characters, but silently discarding the 999th and later characters in a line without warning would still be bad behavior for an implementation ๐Ÿ™…โ€โ™€๏ธ. It's up to the implementation to deal with messages robustly ๐Ÿ’–

One important difference between the obsolete (interpreting) syntax and the current (generating) syntax is that in structured header field bodies (meaning between the colon and the CRLF of any structured header field), white space characters, including folding white space, and comments can be freely inserted between any syntactic tokens ๐Ÿง That allows lots of complex forms that were hard for some implementations to parse ๐ŸŒˆ

Another key difference is that the rule in section 3.2.3 about lines made entirely of white space in comments and folding white space does not apply here. See the discussion of folding white space in section 4.2 below ๐Ÿ‘‘

Finally, some characters that used to be allowed in messages show up in this section. The NUL character (ASCII value 0) was once allowed but no longer is, for compatibility reasons. CR and LF were allowed to appear in messages other than as CRLF, and that use is also shown here ๐Ÿฆ‹

Other differences in syntax and semantics are noted in the following sections โœจ

4.1. Miscellaneous obsolete tokens ๐Ÿงš

These syntactic elements get used elsewhere in the obsolete syntax or in the main syntax. The obs-char and obs-qp elements each add ASCII value 0. Bare CR and bare LF get added to obs-text and obs-utext. The period character gets added to obs-phrase. The obs-phrase-list lets you have "empty" elements in a comma-separated list of phrases ๐Ÿ’…

Note: The "period" (or "full stop") character (".") in obs-phrase is not a form that was allowed in earlier versions of this or any other standard. Period (nor any other character from specials) wasn't allowed in phrase, because it made it hard to tell phrases apart from portions of an addr-spec (see section 4.4) ๐Ÿ™ˆ It shows up here because period is currently used in lots of messages in the display-name portion of addresses, especially for initials in names, so it has to be interpreted properly ๐Ÿซถ In the future, period may appear in the regular syntax of phrase ๐Ÿ”ฎ

obs-qp          =       "\" (%d0-127)

obs-text        =       *LF *CR *(obs-char *LF *CR)
obs-char        =       %d0-9 / %d11 /          ; %d0-127 except CR and
                        %d12 / %d14-127         ;  LF

obs-utext       =       obs-text

obs-phrase      =       word *(word / "." / CFWS)

obs-phrase-list =       phrase / 1*([phrase] [CFWS] "," [CFWS]) [phrase]

Bare CR and bare LF show up in messages with two different meanings ๐Ÿ“. Often they get used wrongly in place of CRLF to mark line separators. Other times, bare CR and bare LF are just used as ASCII control characters with their traditional ASCII meanings ๐Ÿ’œ

4.2. Obsolete folding white space ๐ŸŒธ

In the obsolete syntax, any amount of folding white space MAY be inserted wherever the obs-FWS rule is allowed. That means two consecutive "folds" can happen in one line, so a line that makes up part of a folded header field could end up made entirely of white space ๐ŸŒ€

obs-FWS         =       1*WSP *(CRLF 1*WSP)

4.3. Obsolete Date and Time ๐Ÿ•ฐ๏ธ

The obsolete date format allows a 2 digit year in the date field, and it allows a list of alphabetic time zone specifications that were used in earlier versions of this standard ๐Ÿ—“๏ธ It also permits comments and folding white space between lots of the tokens ๐Ÿ’…

obs-day-of-week =       [CFWS] day-name [CFWS]

obs-year        =       [CFWS] 2*DIGIT [CFWS]

obs-month       =       CFWS month-name CFWS

obs-day         =       [CFWS] 1*2DIGIT [CFWS]

obs-hour        =       [CFWS] 2DIGIT [CFWS]

obs-minute      =       [CFWS] 2DIGIT [CFWS]

obs-second      =       [CFWS] 2DIGIT [CFWS]

obs-zone        =       "UT" / "GMT" /          ; Universal Time

                                                ; North American UT
                                                ; offsets
                        "EST" / "EDT" /         ; Eastern:  - 5/ - 4
                        "CST" / "CDT" /         ; Central:  - 6/ - 5
                        "MST" / "MDT" /         ; Mountain: - 7/ - 6
                        "PST" / "PDT" /         ; Pacific:  - 8/ - 7

                        %d65-73 /               ; Military zones - "A"
                        %d75-90 /               ; through "I" and "K"
                        %d97-105 /              ; through "Z", both
                        %d107-122               ; upper and lower case

Okay, so for years with two or three digits: a two digit year from 00 to 49 gets 2000 added, landing between 2000 and 2049. A two digit year from 50 to 99, or any three digit year, gets 1900 added ๐ŸŽ‚

In the obsolete time zone, "UT" and "GMT" mean "Universal Time" and "Greenwich Mean Time", and they're both semantically identical to "+0000" ๐ŸŒ

The other three character zones are the US time zones ๐Ÿ‡บ๐Ÿ‡ธ. The first letter, "E", "C", "M", or "P", stands for "Eastern", "Central", "Mountain", or "Pacific". The second letter is either "S" for "Standard" time or "D" for "Daylight" (or summer) time ๐ŸŒž. Here's how they're interpreted:

EDT is semantically equivalent to -0400
EST is semantically equivalent to -0500
CDT is semantically equivalent to -0500
CST is semantically equivalent to -0600
MDT is semantically equivalent to -0600
MST is semantically equivalent to -0700
PDT is semantically equivalent to -0700
PST is semantically equivalent to -0800

The 1 character military time zones were defined in a non-standard way in [RFC822], so their meaning is unpredictable ๐Ÿซ  The original definitions of the military zones "A" through "I" are equivalent to "+0100" through "+0900" respectively. "K", "L", and "M" are equivalent to "+1000", "+1100", and "+1200" respectively. "N" through "Y" are equivalent to "-0100" through "-1200" respectively, and "Z" is equivalent to "+0000". However, because of the error in [RFC822], they SHOULD all be considered equivalent to "-0000" unless there is out-of-band information confirming their meaning ๐ŸŒ™

Other multi-character (usually between 3 and 5) alphabetic time zones have shown up in Internet messages too. Any such time zone whose meaning is not known SHOULD be considered equivalent to "-0000" unless there is out-of-band information confirming their meaning โญ

4.4. Obsolete Addressing ๐Ÿ“ฌ

There are three main differences in addressing ๐Ÿ’Œ. First, mailbox addresses were allowed to have a route portion before the addr-spec when enclosed in "<" and ">". The route is just a comma-separated list of domain names, each preceded by "@", and the list ends with a colon ๐Ÿ›ฃ๏ธ. Second, CFWS were allowed between the period-separated elements of local-part and domain (so dot-atom wasn't used). On top of that, local-part could contain a quoted-string as well as an atom ๐ŸŽ€. Finally, mailbox-list and address-list were allowed to have "null" members, meaning there could be two or more commas in a row in such a list with nothing in between them ๐Ÿ™ƒ

obs-angle-addr  =       [CFWS] "<" [obs-route] addr-spec ">" [CFWS]

obs-route       =       [CFWS] obs-domain-list ":" [CFWS]

obs-domain-list =       "@" domain *(*(CFWS / "," ) [CFWS] "@" domain)

obs-local-part  =       word *("." word)

obs-domain      =       atom *("." atom)

obs-mbox-list   =       1*([mailbox] [CFWS] "," [CFWS]) [mailbox]

obs-addr-list   =       1*([address] [CFWS] "," [CFWS]) [address]

When interpreting addresses, the route portion SHOULD be ignored ๐Ÿงšโ€โ™€๏ธ๐Ÿ’–

4.5. Obsolete header fields ๐ŸŽ€

Okay so the big difference in the obsolete field syntax is that it lets you have multiple copies of any field, and they can show up in any order. ๐Ÿ™ˆ Also, you're allowed to have any amount of white space before the ":" at the end of a field name. Chaotic, but iconic.

obs-fields      =       *(obs-return /
                        obs-received /
                        obs-orig-date /
                        obs-from /
                        obs-sender /
                        obs-reply-to /
                        obs-to /
                        obs-cc /
                        obs-bcc /
                        obs-message-id /
                        obs-in-reply-to /
                        obs-references /
                        obs-subject /
                        obs-comments /
                        obs-keywords /
                        obs-resent-date /
                        obs-resent-from /
                        obs-resent-send /
                        obs-resent-rply /
                        obs-resent-to /
                        obs-resent-cc /
                        obs-resent-bcc /
                        obs-resent-mid /
                        obs-optional)

Here's the tea โ˜•: apart from destination address fields (more on those in Section 4.5.3 ๐Ÿ’…), what happens when you get several copies of a field is unspecified. Same goes for trace and resent fields that aren't sitting in blocks stuck to the front of the message. ๐Ÿซ  Unless a section below says otherwise, every other field gets interpreted exactly the same way as its non-obsolete twin back in Section 3. No new rules, just the old vibes. โœจ

4.5.1. Obsolete origination date field ๐Ÿ—“๏ธ

obs-orig-date   =       "Date" *WSP ":" date-time CRLF

4.5.2. Obsolete originator fields ๐Ÿ’Œ

obs-from        =       "From" *WSP ":" mailbox-list CRLF

obs-sender      =       "Sender" *WSP ":" mailbox CRLF

obs-reply-to    =       "Reply-To" *WSP ":" mailbox-list CRLF

4.5.3. Obsolete destination address fields ๐Ÿ“ฌ

obs-to          =       "To" *WSP ":" address-list CRLF

obs-cc          =       "Cc" *WSP ":" address-list CRLF

obs-bcc         =       "Bcc" *WSP ":" (address-list / [CFWS]) CRLF

If a message has several copies of a destination address field, they SHOULD be treated as one big list ๐Ÿซถ: take the address-list from the first copy, then tack on the address lists from the later copies, separated by a comma. Sharing is caring. ๐Ÿ’–

4.5.4. Obsolete identification fields ๐Ÿชช

The obsolete "In-Reply-To:" and "References:" fields are a little messier than the current ones ๐Ÿ™ƒ because they let phrases (plain words or quoted strings) show up. On top of that, the obsolete forms of the two sides of msg-id can have CFWS scattered through them, which makes them look exactly like local-part and domain. Twins. ๐Ÿ‘ฏ

obs-message-id  =       "Message-ID" *WSP ":" msg-id CRLF

obs-in-reply-to =       "In-Reply-To" *WSP ":" *(phrase / msg-id) CRLF

obs-references  =       "References" *WSP ":" *(phrase / msg-id) CRLF

obs-id-left     =       local-part

obs-id-right    =       domain

When it comes to interpreting things, the phrases in "In-Reply-To:" and "References:" just get ignored. Bye, phrases. ๐Ÿ‘‹

Also, none of the optional CFWS around the local-part and the domain counts as part of obs-id-left or obs-id-right. That CFWS is basically invisible in the meaning. ๐Ÿซฅ

4.5.5. Obsolete informational fields ๐Ÿ“

obs-subject     =       "Subject" *WSP ":" unstructured CRLF

obs-comments    =       "Comments" *WSP ":" unstructured CRLF

obs-keywords    =       "Keywords" *WSP ":" obs-phrase-list CRLF

4.5.6. Obsolete resent fields ๐Ÿ”

The obsolete syntax also adds a "Resent-Reply-To:" field ๐ŸŒธ. It's built from the field name, optional comments and folding white space, a colon, and a comma-separated list of addresses.

obs-resent-from =       "Resent-From" *WSP ":" mailbox-list CRLF

obs-resent-send =       "Resent-Sender" *WSP ":" mailbox CRLF
obs-resent-date =       "Resent-Date" *WSP ":" date-time CRLF

obs-resent-to   =       "Resent-To" *WSP ":" address-list CRLF

obs-resent-cc   =       "Resent-Cc" *WSP ":" address-list CRLF

obs-resent-bcc  =       "Resent-Bcc" *WSP ":"
                         (address-list / [CFWS]) CRLF

obs-resent-mid  =       "Resent-Message-ID" *WSP ":" msg-id CRLF

obs-resent-rply =       "Resent-Reply-To" *WSP ":" address-list CRLF

Just like the other resent fields, "Resent-Reply-To:" is trace information only ๐Ÿ•ต๏ธโ€โ™€๏ธ. It's a receipt, not a vibe.

4.5.7. Obsolete trace fields ๐Ÿ›ค๏ธ

The obs-return and obs-received are repeated here as template definitions, same as return and received in Section 3 ๐Ÿ”„. Their full syntax lives in [RFC2821].

obs-return      =       "Return-Path" *WSP ":" path CRLF

obs-received    =       "Received" *WSP ":" name-val-list CRLF

obs-path        =       obs-angle-addr

4.5.8. Obsolete optional fields ๐Ÿงฉ

obs-optional    =       field-name *WSP ":" unstructured CRLF

Any field name at all, followed by whatever unstructured text you like. Anything goes. ๐ŸŒˆ


5. Security Considerations ๐Ÿ”

Okay bestie, this part is SERIOUS, so read it carefully ๐Ÿšจ. Care needs to be taken when you're showing messages on a terminal or terminal emulator ๐Ÿ–ฅ๏ธ. Powerful terminals can act on escape sequences and other combinations of ASCII control characters, and the consequences can be wild. They can remap your keyboard or allow other changes to the terminal, which could lead to denial of service or even damaged data ๐Ÿ’€. They can trigger answerback messages (sometimes programmable ones) that let a message make commands run on the recipient's behalf ๐Ÿ˜ฑ. They can also mess with terminal-attached devices like printers ๐Ÿ–จ๏ธ.

Message viewers might want to strip potentially dangerous terminal escape sequences from a message before displaying it ๐Ÿงน. BUT, other escape sequences show up in messages for legit useful reasons (see [RFC2045, RFC2046, RFC2047, RFC2048, RFC2049, ISO2022]), so they should not be stripped indiscriminately. Not everything is trash, periodt. ๐Ÿ’…

Sending non-text objects in messages brings extra security issues too ๐Ÿ“Ž. These are discussed in [RFC2045, RFC2046, RFC2047, RFC2048, RFC2049].

Now the big one ๐Ÿ‘€. Lots of implementations use the "Bcc:" (blind carbon copy) field from Section 3.6.3 ๐Ÿ™ˆ so they can send messages to people without revealing their addresses to the other recipients. If you mishandle this, confidential information can leak ๐Ÿ˜ฌ, and that can eventually lead to security problems, even just from people knowing a particular mail address exists.

For example, if you use the first method from Section 3.6.3, where the "Bcc:" line gets removed from the message, the blind recipients have no explicit sign that they got a blind copy, except that their address doesn't appear in the header ๐Ÿซฃ. So one of the blind addressees could hit reply-all to the shown recipients and accidentally reveal that the message went to the blind recipient. Oops. ๐Ÿ™ƒ

When the second method from Section 3.6.3 is used, the blind recipient's address shows up in the "Bcc:" field of a separate copy of the message ๐Ÿ“จ. If the "Bcc:" field that gets sent includes all of the blind addressees, then every "Bcc:" recipient will see all of the other "Bcc:" recipients ๐Ÿ˜ฑ. And even if each "Bcc:" recipient gets their own message with only their individual address, implementations still need to be careful when processing replies to the message, as described in Section 3.6.3, so they don't accidentally reveal the blind recipient to the other recipients. Be careful out there, babe. ๐Ÿซถ


6. Bibliography ๐Ÿ“š

  • [ASCII] American National Standards Institute (ANSI), Coded Character Set - 7-Bit American National Standard Code for Information Interchange, ANSI X3.4, 1986. ๐Ÿ”ค
  • [ISO2022] International Organization for Standardization (ISO), Information processing - ISO 7-bit and 8-bit coded character sets - Code extension techniques, Third edition - 1986-05-01, ISO 2022, 1986. ๐ŸŒ
  • [RFC822] Crocker, D., "Standard for the Format of ARPA Internet Text Messages", RFC 822, August 1982. ๐Ÿ•ฐ๏ธ
  • [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, November 1996. ๐Ÿ“ฆ
  • [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, November 1996. ๐ŸŽž๏ธ
  • [RFC2047] Moore, K., "Multipurpose Internet Mail Extensions (MIME) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, November 1996. ๐ŸŒ
  • [RFC2048] Freed, N., Klensin, J. and J. Postel, "Multipurpose Internet Mail Extensions (MIME) Part Four: Format of Internet Message Bodies", RFC 2048, November 1996. ๐Ÿ—‚๏ธ
  • [RFC2049] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples", RFC 2049, November 1996. โœ…
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. ๐Ÿ—๏ธ
  • [RFC2234] Crocker, D., Editor, and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 2234, November 1997. ๐Ÿงฎ
  • [RFC2821] Klensin, J., Editor, "Simple Mail Transfer Protocol", RFC 2821, March 2001. ๐Ÿ“ฎ
  • [STD3] Braden, R., "Host Requirements", STD 3, RFC 1122 and RFC 1123, October 1989. ๐Ÿ 
  • [STD12] Mills, D., "Network Time Protocol", STD 12, RFC 1119, September 1989. โฐ
  • [STD13] Mockapetris, P., "Domain Name System", STD 13, RFC 1034 and RFC 1035, November 1987. ๐ŸŒ
  • [STD14] Partridge, C., "Mail Routing and the Domain System", STD 14, RFC 974, January 1986. ๐Ÿ—บ๏ธ

7. Editor's Address ๐Ÿ’Œ

Peter W. Resnick
QUALCOMM Incorporated
5775 Morehouse Drive
San Diego, CA 92121-1714
USA

Phone: +1 858 651 4478
Fax:   +1 858 651 1102
EMail: presnick@qualcomm.com

8. Acknowledgements โœจ

Okay bestie, SO many people helped make this doc happen ๐Ÿซถ That includes folks from the Detailed Revision and Update of Messaging Standards (DRUMS) Working Group of the Internet Engineering Task Force (IETF), the DRUMS chair, the IETF Area Directors, and people who just emailed their comments in ๐Ÿ’Œ The editor is deeply indebted to all of them and thanks them sincerely ๐Ÿ’œ The list below has everyone who sent an email about this document. Hopefully everyone who contributed is in there:

Matti Aarnio              Barry Finkel           Larry Masinter
Tanaka Akira              Erik Forsberg          Denis McKeon
Russ Allbery              Chuck Foster           William P McQuillan
Eric Allman               Paul Fox               Alexey Melnikov
Harald Tveit Alvestrand   Klaus M. Frank         Perry E. Metzger
Ran Atkinson              Ned Freed              Steven Miller
Jos Backus                Jochen Friedrich       Keith Moore
Bruce Balden              Randall C. Gellens     John Gardiner Myers
Dave Barr                 Sukvinder Singh Gill   Chris Newman
Alan Barrett              Tim Goodwin            John W. Noerenberg
John Beck                 Philip Guenther        Eric Norman
J. Robert von Behren      Tony Hansen            Mike O'Dell
Jos den Bekker            John Hawkinson         Larry Osterman
D. J. Bernstein           Philip Hazel           Paul Overell
James Berriman            Kai Henningsen         Jacob Palme
Norbert Bollow            Robert Herriot         Michael A. Patton
Raj Bose                  Paul Hethmon           Uzi Paz
Antony Bowesman           Jim Hill               Michael A. Quinlan
Scott Bradner             Paul E. Hoffman        Eric S. Raymond
Randy Bush                Steve Hole             Sam Roberts
Tom Byrer                 Kari Hurtta            Hugh Sasse
Bruce Campbell            Marco S. Hyman         Bart Schaefer
Larry Campbell            Ofer Inbar             Tom Scola
W. J. Carpenter           Olle Jarnefors         Wolfgang Segmuller
Michael Chapman           Kevin Johnson          Nick Shelness
Richard Clayton           Sudish Joseph          John Stanley
Maurizio Codogno          Maynard Kang           Einar Stefferud
Jim Conklin               Prabhat Keni           Jeff Stephenson
R. Kelley Cook            John C. Klensin        Bernard Stern
Steve Coya                Graham Klyne           Peter Sylvester
Mark Crispin              Brad Knowles           Mark Symons
Dave Crocker              Shuhei Kobayashi       Eric Thomas
Matt Curtin               Peter Koch             Lee Thompson
Michael D'Errico          Dan Kohn               Karel De Vriendt
Cyrus Daboo               Christian Kuhtz        Matthew Wall
Jutta Degener             Anand Kumria           Rolf Weber
Mark Delany               Steen Larsen           Brent B. Welch
Steve Dorner              Eliot Lear             Dan Wing
Harold A. Driscoll        Barry Leiba            Jack De Winter
Michael Elkins            Jay Levitt             Gregory J. Woodhouse
Robert Elz                Lars-Johan Liman       Greg A. Woods
Johnny Eriksson           Charles Lindsey        Kazu Yamamoto
Erik E. Fair              Pete Loshin            Alain Zahm
Roger Fajman              Simon Lyall            Jamie Zawinski
Patrik Faltstrom          Bill Manning           Timothy S. Zurcher
Claus Andre Farber        John Martin

Appendix A. Example messages ๐ŸŽ€

This section is a little collection of messages to help you build the standard, but these examples are not the official rules ๐Ÿ’… If one of them ever clashes with the syntax in sections 3 and 4 of this document, those sections win. Every single time ๐Ÿ‘‘ The examples were carefully reviewed, but the syntax is the source of truth.

Messages are separated by lines of "----" in this section. Those lines are just dividers and not part of the message itself ๐Ÿฆ‹

A.1. Addressing examples

Here are some messages that might get sent between two people ๐Ÿ’•

A.1.1. A message from one person to another with simple addressing

This is what we'd call a canonical message ๐Ÿ“ It has one author (John Doe), one recipient (Mary Smith), a subject, the date, a message identifier, and a text body.

----
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>

This is a message just to say hello.
So, "Hello".
----

Now say John's secretary Michael actually sent it. John is still the author, and replies should go back to him, so the sender field gets used ๐Ÿงš

----
From: John Doe <jdoe@machine.example>
Sender: Michael Jones <mjones@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>

This is a message just to say hello.
So, "Hello".
----

A.1.2. Different types of mailboxes

This one has multiple addresses in the destination fields and uses a bunch of different address forms. It's giving variety show ๐ŸŒˆ

----
From: "Joe Q. Public" <john.q.public@example.com>
To: Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>
Cc: <boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>
Date: Tue, 1 Jul 2003 10:52:37 +0200
Message-ID: <5678.21-Nov-1997@example.com>

Hi everyone.
----

Notice that Joe Q. Public and Giant; "Big" Box need double-quotes, because the first has a period and the second has a semicolon and double-quote characters (those double-quotes show up as a quoted-pair construct). Who? doesn't need them, because a question mark is legal inside an atom ๐Ÿ™ˆ Also, jdoe@example.org and boss@nil.test have no display names at all, and jdoe@example.org uses the simpler address form without angle brackets. Iconic ๐Ÿ’…

A.1.3. Group addresses

----
From: Pete <pete@silly.example>
To: A Group:Chris Jones <c@a.test>,joe@where.test,John <jdoe@one.test>;
Cc: Undisclosed recipients:;
Date: Thu, 13 Feb 1969 23:32:54 -0330
Message-ID: <testabcd.1234@silly.example>

Testing.
----

In this one, the "To:" field has a single group recipient called A Group, which holds 3 addresses. The "Cc:" field has an empty group recipient called Undisclosed recipients ๐ŸŒธ

A.2. Reply messages

This is a little conversation thread between John and Mary ๐Ÿ’ฌ John sends the first message to Mary, Mary replies to John, and then John replies to Mary's reply. Look closely at the "Message-ID:", "References:", and "In-Reply-To:" fields in each message ๐Ÿ”

----
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>

This is a message just to say hello.
So, "Hello".
----

When you reply, the Subject field usually stays, but it gets "Re: " stuck on the front, as described in section 3.6.5 โœจ

----
From: Mary Smith <mary@example.net>
To: John Doe <jdoe@machine.example>
Reply-To: "Mary Smith: Personal Account" <smith@home.example>
Subject: Re: Saying Hello
Date: Fri, 21 Nov 1997 10:01:10 -0600
Message-ID: <3456@example.net>
In-Reply-To: <1234@local.machine.example>
References: <1234@local.machine.example>

This is a reply to your hello.
----

Mary's message has a "Reply-To:" field. When John replies, the reply should go to the address in "Reply-To:" instead of the one in "From:" ๐Ÿซถ

----
To: "Mary Smith: Personal Account" <smith@home.example>
From: John Doe <jdoe@machine.example>
Subject: Re: Saying Hello
Date: Fri, 21 Nov 1997 11:00:00 -0600
Message-ID: <abcd.1234@local.machine.tld>
In-Reply-To: <3456@example.net>
References: <1234@local.machine.example> <3456@example.net>

This is a reply to your reply.
----

A.3. Resent messages

Let's start with the message we've been using as an example all along ๐Ÿงธ

----
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>

This is a message just to say hello.
So, "Hello".
----

Okay, so Mary gets this and wants to send a copy to Jane ๐Ÿ’Œ She wants three things: (a) the message should look like it came straight from John; (b) if Jane replies, the reply should go back to John; and (c) all the original info, like the date Mary got it, the message identifier, and the original addressee, stays put. To do that, resent fields get prepended to the message ๐Ÿ’–

Resent-From: Mary Smith <mary@example.net>
Resent-To: Jane Brown <j-brown@other.example>
Resent-Date: Mon, 24 Nov 1997 14:22:01 -0800
Resent-Message-ID: <78910@example.net>
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>

This is a message just to say hello.
So, "Hello".

If Jane wants to pass it along to someone else, she prepends her own set of resent header fields to the above and sends that on ๐Ÿฆ‹

A.4. Messages with trace fields

Messages travel through the transport system as described in [RFC2821], and trace fields get prepended as they go ๐Ÿš€ Here's what those trace fields might look like. The first one has some folding white space, since those lines can get long.

Received: from x.y.test
   by example.net
   via TCP
   with ESMTP
   id ABC12345
   for <mary@example.net>;  21 Nov 1997 10:05:43 -0600
Received: from machine.example by x.y.test; 21 Nov 1997 10:01:22 -0600
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>

This is a message just to say hello.
So, "Hello".

A.5. White space, comments, and other oddities

Here's the fun part ๐ŸŒˆ White space (including folding white space) and comments can get tucked into a lot of the tokens inside fields. Using the example from A.1.3, we'll sprinkle white space and comments into every single field ๐Ÿ™ˆ

From: Pete(A wonderful \) chap) <pete(his account)@silly.test(his host)>
To:A Group(Some people)
     :Chris Jones <c@(Chris's host.)public.example>,
         joe@example.org,
  John <jdoe@one.test> (my dear friend); (the end of the group)
Cc:(Empty list)(start)Undisclosed recipients  :(nobody(that I know))  ;
Date: Thu,
      13
        Feb
          1969
      23:32
               -0330 (Newfoundland Time)
Message-ID:              <testabcd.1234@silly.test>

Testing.

Appendix A. Examples ๐Ÿ’– (continued)

The above example is aesthetically displeasing, but perfectly legal ๐Ÿ’… Look closely at all of these things ๐Ÿ‘€:

  1. The comments in the From: field, including one with a ) character hiding inside a quoted-pair ๐ŸŽ€
  2. The missing white space after the : in the To: field, the comment and folding white space after the group name, the special character (.) inside the comment in Chris Jones's address, and the folding white space before and after joe@example.org, ๐ŸŒธ
  3. The multiple, nested comments in the Cc: field, plus the comment right after the : following Cc ๐Ÿฆ‹
  4. The folding white space (with no comments except at the very end) and the missing seconds in the time of the date field โญ
  5. The white space before (but not within) the identifier in the Message-ID: field ๐Ÿงš

A.6. Obsoleted forms ๐Ÿ™ˆ

These are examples of obsolete syntactic elements from section 4 of this document. Obsolete means the "MUST NOT generate" kind ๐Ÿ’€, so they're here as a warning, not a template ๐Ÿšซ

A.6.1. Obsolete addressing ๐Ÿ“

In this one, Joe Q. Public has no quotes around his name, Mary Smith's address has a route in it, the To: field has two commas in a row, and there are spaces around the . in the jdoe address ๐Ÿ˜ญ

From: Joe Q. Public <john.q.public@example.com>
To: Mary Smith <@machine.tld:mary@example.net>, , jdoe@test   . example
Date: Tue, 1 Jul 2003 10:52:37 +0200
Message-ID: <5678.21-Nov-1997@example.com>

Hi everyone.

A.6.2. Obsolete dates ๐Ÿ—“๏ธ

This message uses an obsolete date format: a non-numeric time zone and a two-digit year. The day-of-week is missing too, but that isn't a special obsolete thing, since it's optional in the current syntax as well โœจ

From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello
Date: 21 Nov 97 09:55:06 GMT
Message-ID: <1234@local.machine.example>

This is a message just to say hello.
So, "Hello".

A.6.3. Obsolete white space and comments ๐Ÿซถ

Okay, this one is chaos in the best way ๐ŸŒˆ Comments and white space can show up between way more elements than in the current syntax, and folding lines that are made up entirely of white space are legal too ๐Ÿ˜ณ

From  : John Doe <jdoe@machine(comment).  example>
To    : Mary Smith
__
          <mary@example.net>
Subject     : Saying Hello
Date  : Fri, 21 Nov 1997 09(comment):   55  :  06 -0600
Message-ID  : <1234   @   local(blah)  .machine .example>

This is a message just to say hello.
So, "Hello".

The big thing to notice is the second line of the To: field ๐Ÿ‘€ It starts with two space characters. (Quick note: __ stands for blank spaces here.) That makes it part of the folding described in section 4.2 ๐ŸŽ€ Also, the comments and white space scattered through the addresses, dates, and message identifiers are all part of the obsolete syntax ๐Ÿ’…


Appendix B. Differences from earlier standards ๐Ÿ“š

This appendix lists the changes made to the Internet Message Format compared to earlier standards, specifically [RFC822] and [STD3] โœจ Anything marked with an asterisk (*) is something that shows up in section 4 of this document, which means it can no longer be generated ๐Ÿ™…โ€โ™€๏ธ

  1. Period allowed in obsolete form of phrase. ๐ŸŒธ
  2. ABNF moved out of document to [RFC2234]. ๐Ÿ“ฆ
  3. Four or more digits allowed for year. ๐Ÿ“…
  4. Header field ordering (and lack thereof) made explicit. ๐Ÿ—‚๏ธ
  5. Encrypted header field removed. ๐Ÿ”
  6. Received syntax loosened to allow any token/value pair. ๐Ÿฆ‹
  7. Specifically allow and give meaning to -0000 time zone. ๐ŸŒ
  8. Folding white space is not allowed between every token. ๐Ÿ™…โ€โ™€๏ธ
  9. Requirement for destinations removed. ๐Ÿ“ญ
  10. Forwarding and resending redefined. ๐Ÿ”
  11. Extension header fields no longer specifically called out. ๐Ÿงฉ
  12. ASCII 0 (null) removed.* ๐Ÿ—‘๏ธ
  13. Folding continuation lines cannot contain only white space.* ๐Ÿซฅ
  14. Free insertion of comments not allowed in date.* โฐ
  15. Non-numeric time zones not allowed.* ๐Ÿšซ
  16. Two digit years not allowed.* ๐Ÿ™ˆ
  17. Three digit years interpreted, but not allowed for generation. ๐Ÿ”
  18. Routes in addresses not allowed.* ๐Ÿ›ฃ๏ธ
  19. CFWS within local-parts and domains not allowed.* ๐ŸŽ€
  20. Empty members of address lists not allowed.* ๐Ÿ“‹
  21. Folding white space between field name and colon not allowed.* ๐Ÿ™…โ€โ™€๏ธ
  22. Comments between field name and colon not allowed. ๐Ÿ’ฌ
  23. Tightened syntax of in-reply-to and references.* ๐Ÿ”—
  24. CFWS within msg-id not allowed.* ๐Ÿ†”
  25. Tightened semantics of resent fields as informational only. โ„น๏ธ
  26. Resent-Reply-To not allowed.* ๐Ÿšท
  27. No multiple occurrences of fields (except resent and received).* 1๏ธโƒฃ
  28. Free CR and LF not allowed.* ๐Ÿšซ
  29. Routes in return path not allowed.* โ†ฉ๏ธ
  30. Line length limits specified. ๐Ÿ“
  31. Bcc more clearly specified. ๐Ÿซฃ

Appendix C. Notices ๐Ÿ””

Intellectual Property โš–๏ธ

Okay, legal stuff, but it's important ๐Ÿซถ The IETF doesn't take a position on whether any intellectual property or other rights someone might claim over the technology in this document are valid, how far they reach, or whether any license under those rights is or isn't available. It also doesn't say it has tried to identify any such rights. For how the IETF handles rights in standards-track and standards-related documentation, check BCP-11 ๐Ÿ“– Copies of rights claims that were made available for publication, plus any assurances of licenses that are going to be made available, or the result of an attempt to get a general license or permission for implementors or users to use those proprietary rights, can be obtained from the IETF Secretariat ๐Ÿ’Œ

Copyright (C) The Internet Society (2001). All Rights Reserved. โœจ

This document and translations of it can be copied and furnished to others. Derivative works that comment on or otherwise explain it, or help with its implementation, can be prepared, copied, published, and distributed, in whole or in part, without restriction of any kind ๐Ÿฆ‹ That's allowed as long as the above copyright notice and this paragraph are included on all such copies and derivative works ๐ŸŽ€

However, this document itself may not be modified in any way, such as by removing the copyright notice or the references to the Internet Society or other Internet organizations ๐Ÿšซ The exceptions are when it's needed for developing Internet standards, in which case the copyright procedures defined in the Internet Standards process must be followed, or when it's required to translate it into languages other than English ๐ŸŒ

The limited permissions above are perpetual, and the Internet Society or its successors or assigns will not revoke them ๐ŸŒˆ

This document and the information in it are provided on an "AS IS" basis, and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ๐Ÿ˜ญ

Acknowledgement ๐ŸŒธ

Funding for the RFC Editor function is currently provided by the Internet Society ๐Ÿ’–

๐Ÿ“ฆ where this page comes from