Last edited: 2026-08-06 09:44:12

Almost every file your software writes to disk and every packet it puts on the wire is described somewhere in a Request for Comments document. RFCs are the specifications that let a calendar written by one vendor open correctly in another, and let a log line emitted by a router be parsed by a collector nobody coordinated with. This article walks through what an RFC is, how the documents are structured, and then reads three of them properly: RFC 6350 (vCard), RFC 5545 (iCalendar), and RFC 5424 (syslog).
The series began in April 1969, when Steve Crocker published RFC 1, "Host Software", as a deliberately informal note among the handful of people building ARPANET. The name was chosen to sound unofficial. Nobody wanted to appear to be issuing decrees, so they asked for comments instead. Nearly six decades later the name has stuck, even though the series now carries the core specifications of the internet: IP, TCP, DNS, HTTP, TLS, and the file formats built on top of them.
Today RFCs are published by the RFC Editor, and most of the ones engineers care about come out of the IETF (Internet Engineering Task Force) after a working group has hammered out a draft and rough consensus has been reached. Two properties make the series unusually pleasant to work with:
That immutability has a practical consequence: the first thing to check when opening any RFC is the banner at the top of the page saying whether it has been obsoleted by something newer. Plenty of production bugs come from implementing a specification that was superseded a decade earlier.
This trips people up constantly. "It's in an RFC" does not mean "it is a standard". Every RFC carries a status:
And then there is the 1st of April series, which contains RFC 1149 (IP over avian carriers) and RFC 2324 (the Hyper Text Coffee Pot Control Protocol, source of HTTP status code 418). These are jokes, but they are numbered, permanent, and formatted exactly like the real ones, which is very much part of the joke.
Before reading any specification it is worth internalising RFC 2119, which defines the requirement keywords used throughout the series. Clarified later by RFC 8174, the rule is that these words carry their special meaning only when written in capitals:
Most interoperability failures in the wild come from reading a SHOULD as a MUST, or a MUST as a suggestion. When a parser rejects a file that a competing parser accepts, the argument is nearly always about one of these words.
vCard is the format behind the .vcf files that phones and address books exchange. Its history is a good illustration of how specifications migrate into the RFC series: version 2.1 was published in 1996 by the versit consortium and was never an RFC at all. Version 3.0 arrived as RFC 2425 and RFC 2426 in 1998, and version 4.0 was published as RFC 6350 in 2011.
The format is a flat sequence of content lines, each of the form NAME;PARAM=value:VALUE:
BEGIN:VCARD
VERSION:4.0
FN:Ada Lovelace
N:Lovelace;Ada;;;
EMAIL;TYPE=work:ada@example.org
TEL;VALUE=uri;TYPE="voice,cell":tel:+46-70-123-4567
END:VCARD
A few design decisions in RFC 6350 are worth pointing out, because they recur in every text-based format the IETF has produced:
VERSION is mandatory and must come first, immediately after BEGIN:VCARD. A parser needs to know which grammar it is dealing with before it reads anything else.N property above carries five components (family, given, additional, prefixes, suffixes), which is why it ends with a run of empty fields.N is no longer mandatory, leaving FN (the formatted display name) as the only required name property, which suits organisations and single-name entities much better.The version differences matter in practice, because an address book that only understands 3.0 will choke on 4.0 constructs like the geo: and tel: URI values. The vCard specification breakdowns at vcfconverter.com lay the three versions out property by property, which is a faster way to check a specific field than diffing the RFCs by hand.
iCalendar (.ics) is the format behind every meeting invitation and calendar subscription feed. RFC 5545 obsoleted RFC 2445 in 2009, and it shares an obvious family resemblance with vCard: the same BEGIN/END block structure, the same content-line grammar, the same 75-octet folding rule. That is not a coincidence, as both descend from the same MIME directory-profile work.
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp//Scheduler 1.0//EN
BEGIN:VEVENT
UID:19970901T130000Z-123401@example.com
DTSTAMP:20260806T090000Z
DTSTART;TZID=Europe/Stockholm:20260810T130000
DTEND;TZID=Europe/Stockholm:20260810T140000
SUMMARY:Design review
RRULE:FREQ=WEEKLY;BYDAY=MO;COUNT=8
END:VEVENT
END:VCALENDAR
Where iCalendar gets genuinely hard is time. The specification permits three distinct forms of date-time value, and confusing them is the single most common source of calendar bugs:
20260810T130000, no timezone at all. Means 13:00 wherever the reader happens to be. Correct for a birthday, wrong for a meeting.20260810T130000Z, with the trailing Z. Unambiguous.DTSTART;TZID=Europe/Stockholm:20260810T130000. This is the form required for recurring meetings, because a weekly 13:00 event must stay at 13:00 across a daylight-saving transition rather than drifting by an hour. It also means the file MUST contain a matching VTIMEZONE component defining that identifier.The other requirements that generators routinely get wrong are UID and DTSTAMP on every event (both mandatory), CRLF line endings rather than bare LF, and RRULE recurrences that illegally combine UNTIL with COUNT. Anyone writing an ICS generator will recognise this list, and the RFC 5545 conformance checks documented by icsfile.com are a useful catalogue of exactly which of them break real calendar clients.
The first two examples are file formats. Syslog is a wire protocol, and it demonstrates a different RFC pattern: what happens when a specification is written after a de-facto standard has already spread everywhere.
Syslog started life in the 1980s as part of Eric Allman's sendmail and was never designed as such. By 2001 it was so ubiquitous that RFC 3164 was published simply to write down what implementations were observed to do. The document is explicitly Informational and, in its own words, describes observed behaviour rather than prescribing a format. It produces messages like:
<34>Oct 11 22:14:15 mymachine su: 'su root' failed for lonvick
That timestamp has no year, no timezone, and no sub-second precision, and the su: tag is a loose convention rather than a defined field. Parsing it reliably across vendors is miserable.
RFC 5424 replaced it in 2009 with a strictly ordered header:
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - 'su root' failed
The fields are, in order: priority, version, timestamp, hostname, app-name, process ID, message ID, structured data, and the message itself. Three details make it far more machine-friendly than its predecessor:
[origin ip="10.0.0.4"] carries key-value pairs directly, and vendors namespace custom identifiers with their IANA private enterprise number (exampleSDID@32473) so two vendors cannot collide.The priority value in angle brackets is not arbitrary either. It packs two numbers into one integer:
where facility runs from 0 (kernel) to 23 (local7) and severity from 0 (emergency) to 7 (debug). So <34> decomposes as facility 4 (security/authorization) and severity 2 (critical), while the very common <14> is facility 1 (user) at severity 6 (informational). A field-by-field walkthrough of the modern format, including the structured-data grammar, is maintained at syslog.tools, and it is a quicker reference than section 6 of the RFC when debugging a parser at three in the morning.
Read enough RFCs and the same structural decisions keep reappearing:
A formal grammar, usually ABNF. RFC 5234 defines Augmented Backus-Naur Form, and most specifications include a complete ABNF section. When prose and grammar seem to disagree, the grammar is normative. If you are writing a parser, the ABNF section is the part to read first and the prose is commentary.
An explicit extension mechanism. vCard and iCalendar both allow X- prefixed properties for private use; syslog allocates namespaced structured-data identifiers. Formats without a defined extension point get extended anyway, just incompatibly.
IANA registries instead of hardcoded lists. Rather than freezing the set of valid values in the document, RFCs delegate to a registry that IANA maintains. This is why new media types or new syslog structured-data identifiers can appear without republishing anything.
Text over binary, and octets over characters. All three formats are line-oriented UTF-8 text, and all three specify limits in octets. That distinction is where multilingual data tends to break.
Security Considerations, always. Every RFC is required to have this section. It is regularly the most interesting part, and in the case of calendar and contact formats it is where the specification is candid about what a malicious file can do to a parser.
RFCs are long, but they are consistently organised, so you rarely need to read one end to end:
Given how much software is written against a vague memory of how a format works rather than the document that defines it, an hour with the actual specification is usually the cheapest debugging any team can do.
Was the post useful? Feel free to donate!
DONATE