Wall of Outdated or Otherwise Misleading Specs
So, uh. IRC specifications. There are a damn lot of them. And a lot of those are outdated or simply misleading. Sure, there’s attempts at writing new ones, but the simple fact is that most out there today that are still referenced are misleading in some way(s).
This page lists the common IRC specs out there, and roughly catalogues the outdated or misleading sections of them.
RFC 1459
1.2 - Clients
The spec reads:
server. Each client is distinguished from other clients by a unique
nickname having a maximum length of nine (9) characters. See the
Nicks are no longer limited to nine characters. See the NICKLEN
RPL_ISUPPORT token for the actual maximum nick length on the network.
1.3 - Channels
The spec reads:
Channels names are strings (beginning with a '&' or '#' character) of
length up to 200 characters. Apart from the the requirement that the
first character being either '&' or '#'; the only restriction on a
Channels can start with any character defined by the CHANTYPES
RPL_ISUPPORT token, and the maximum channel name length is defined by the CHANNELLEN
token.
The spec reads:
think is in each channel and the mode of that channel. If the
channel exists on both sides, the JOINs and MODEs are interpreted in
an inclusive manner so that both sides of the new connection will
agree about which clients are in the channel and what modes the
channel has.
Modes aren’t strictly interpreted in an inclusive manner. Commonly, server-to-server (S2S) protocols use some sort of timestamping function to ensure clients can’t exploit netsplits to incorrectly give themselves permissions. Servers should agree about exactly what modes the channel has, in any case.
1.3.1 - Channel Operators
These days there are also different levels of channel moderator, including ‘halfops’ (half operators), ‘protected ops’, and the ‘founder’ rank. These moderation levels have varying privileges and can execute, and not execute, various channel management commands based on what the server defines.
These channel moderators also have different prefixes, defined by the PREFIX
RPL_ISUPPORT token.
2.1 - The IRC Specification Overview
The spec reads:
The protocol as described herein is for use both with server to
server and client to server connections. There are, however, more
This protocol is only used for client connections. Server protocols these days are varied and while some (such as TS6 and P10) are based on this original S2S protocol, others may not be.
For the best guide on a server’s S2S protocol, look at the documentation+code for the specific IRC server you’re using.
2.2 - Character codes
The spec reads:
No specific character set is specified.
While this is accurate, UTF-8 has become the generally-accepted standard encoding for sending messages on IRC. When decoding, using a combination of UTF-8 and Latin-1/ISO-8859-1(5)/CP1252 is best. See this page for further discussion on character sets with the client protocol.
The spec reads:
Because of IRC's scandanavian origin, the characters {}| are
considered to be the lower case equivalents of the characters []\,
respectively. This is a critical issue when determining the
equivalence of two nicknames.
This is true for servers following rfc1459
casefolding. However, servers may not do this. To discover the specific casefolding rules the server has in place, see the CASEMAPPING
RPL_ISUPPORT token.
2.3.1 - Message format in 'pseudo' BNF
See the IRCv3 Message Tags specification for info regarding updates to this.
4.1 - Connection Registration
The spec reads:
A "PASS" command is not required for either client or server
connection to be registered, but it must precede the server message
or the latter of the NICK/USER combination. It is strongly
recommended that all server connections have a password in order to
give some level of security to the actual connections. The
recommended order for a client to register is as follows:
1. Pass message
2. Nick message
3. User message
There are a few more commands that can be used during connection registration, and some specific numerics that are sent once registration is completed. See this page for a more accurate overview of connection registration.
4.1.3 - User message
The spec reads:
Command: USER
Parameters: <username> <hostname> <servername> <realname>
...
Note that hostname and servername are normally ignored by the IRC
server when the USER command comes from a directly connected client
(for security reasons), but they are used in server to server
communication. This means that a NICK must always be sent to a
This is correct, and I point it out because client and server authors often mistakenly believe the <hostname>
and <servername>
parameters for parameters that they should actually send real data for or parse. Particularly because of differences between RFC 1459 and RFC 2812, clients should just send "0 *"
for the <hostname>
and <servername>
parameters.
Many servers also prefix usernames given to them by the client with a '~'
character, to note that it is user-supplied rather than having been retrieved from an identity server. See this page for more discussion on this.
4.1.5 - Oper message
The specific failure cases for this command, and what to do when they’re encountered, are expanded on here.
4.1.6 - Quit message
These days, servers prepend "Quit: "
to user-provided quit messages to separate them from other protocol or server issues. In addition, quits created due to netsplits often don’t contain the actual names of servers and use the fake server names "*.net *.split"
. This is expanded on here.
4.2 - Channel operations
The spec reads:
ultimately clash. It is also required that servers keep a nickname
history to ensure that wherever a <nick> parameter is given, the
server check its history in case it has recently been changed.
These days, S2S protocols generally use a timestamp-based approach to prevent these issues from happening, rather than nick-delay solutions. Because of this, the recently-changed-nicks history isn’t required.
4.2.1 - Join message
In addition to the elements affecting this command listed here, there are now ban and invite exceptions, the channel limit noted by CHANLIMIT
, and the special argument of '0'
which some servers accept. See a more accurate description of this command here.
4.2.2 - Part message
See here for a more in-depth explanation of this command, as well as exactly how it’s relayed to other clients.
4.2.3 - Mode message
The spec reads:
The MODE command is a dual-purpose command in IRC. It allows both
usernames and channels to have their mode changed. The rationale for
this choice is that one day nicknames will be obsolete and the
equivalent property will be the channel.
I haven’t been able to find any reasonable meaning in the phrase “one day nicknames will be obsolete and the equivalent property will be the channel”. It means nothing, and nicknames are just as relevant as they’ve always been.
In addition, the described message format for both channel and user modes is incorrect ('+'
and '-'
are now allowed at any point in a modestring).
For a wildly more accurate definition of this command, see here.
4.2.3.1 - Channel modes
As noted above, the message format is incorrect as '+'
and '-'
are now allowed anywhere in a modestring.
The specific list of channel modes here is outdated – ’private’ is no longer standard, and there are a few more standard modes out there. See here for an updated list.
There are now several ‘types’ of channel modes which are defined with the CHANMODES
RPL_ISUPPORT token. See here for further discussion on this and how it’s implemented today.
The spec also reads:
When using the 'o' and 'b' options, a restriction on a total of three
per mode command has been imposed. That is, any combination of 'o'
and
In addition to the mistaken cut-off text here, these restrictions are now defined by the MODES
RPL_ISUPPORT parameter.
4.2.3.2 - User modes
As noted above, the message format is incorrect as '+'
and '-'
are now allowed anywhere in a modestring.
The list of user modes here is outdated, and there are some other standard ones. See here for a slightly-updated list.
RFC 2810
2.2 - Clients
The spec reads:
User clients are generally programs providing a text based
interface that is used to communicate interactively via IRC. This
particular type of clients is often referred as "users".
...
Unlike users, service clients are not intended to be used manually
nor for talking. They have a more limited access to the chat
functions of the protocol, while optionally having access to more
private data from the servers.
While in practice, both ‘bots’ and ‘pseudo-servers’ that create fake clients are used with IRC, the user-clients vs service-clients split described in this section is not accurate. It would be more accurate to frame the different clients as such:
- True Clients: These are clients that connect to servers using the IRC client protocol. They can be controlled by a human user, a bot program, or some combination of the two.
- Fake Clients: These are clients that are introduced through the S2S protocol, but are not actual externally-connected clients. Some examples of this are the NickServ and ChanServ clients common on networks.
3 - Architecture
The spec reads:
The IRC protocol provides no mean for two clients to directly
communicate. All communication between clients is relayed by the
server(s).
While this is accurate (the IRC protocol itself doesn’t provide this), the DCC protocol does provide this.
6.1 - Scalability
The spec reads:
It is widely recognized that this protocol does not scale
sufficiently well when used in a large arena. The main problem comes
from the requirement that all servers know about all other servers,
clients and channels and that information regarding them be updated
as soon as it changes.
While mostly accurate, some S2S protocols only share a limited amount of information with other servers – for instance, not sharing detailed channel information with a server unless there’s a client connected to that channel on the server. These sort of workarounds try to help address this issue.
RFC 2811
2.4.2 - Channel Creator
The spec reads:
A user who creates a channel with the character '!' as prefix is
identified as the "channel creator". Upon creation of the channel,
this user is also given channel operator status.
These days, this ‘channel creator’ role has generally been replaced with a ‘channel founder’ role using the channel member prefix '~'
(which is only used when the server supports user account registration and channel ownership via ChanServ or similar).
3. - Channel lifetime
The spec reads:
In regard to the lifetime of a channel, there are typically two
groups of channels: standard channels which prefix is either '&', '#'
or '+', and "safe channels" which prefix is '!'.
‘Safe channels’ aren’t implemented these days. You can still find a couple networks out there that support them, but they’re very few and far between. It’s more appropriate to say that there are two groups of channels in regards to lifetimes:
- Unregistered channels act as described in the Standard Channels (3.1) section, with the caveats listed below.
- Registered channels have long lifetimes, lasting longer than the life of the clients connected to it and usually longer than the life of the ircd itself (around 90-120 days is relatively common).
See how ChanServ works for a better representation of channel lifetimes than I’m giving here.
3.1 - Standard channels
The spec reads:
The user creating a channel automatically becomes channel operator
with the notable exception of channels which name is prefixed by the
character '+', see section 4 (Channel modes). See section 2.4.1
(Channel Operators) for more details on this title.
As with ‘safe channels’ above, these sort of channels aren’t widely available or implemented these days.
The spec also reads:
In order to avoid the creation of duplicate channels (typically when
the IRC network becomes disjoint because of a split between two
servers), channel names SHOULD NOT be allowed to be reused by a user
if a channel operator (See Section 2.4.1 (Channel Operators)) has
recently left the channel because of a network split. If this
...
the character '+'. This mechanism is commonly known as "Channel
Delay".
Channel delay has largely been replaced with systems that rely on timestamps to appropriately merge channels when the two sides of the network rejoin. However, this issue mostly relies on how the server-to-server (S2S) protocol of the specific ircd you’re using has been implemented. Check your server’s S2S code+documentation for more accurate information for how they’ve chosen to implement this.
4 - Channel Modes
This section has a list of channel modes. For an updated list of modes that are commonly-implemented across servers, I’d recommend seeing this page instead.
4.1 - Member Status
This section lists a series of membership prefixes and levels. The ‘channel creator’ status has largely been replaced with the ones listed on this page, which I’d recommend consulting instead.
4.2 - Channel Flags
As noted above, some of the flags listed here aren’t actually widely-implemented or standard across different servers. See this page for a more accurate list of what’s out there today.
5.1 - Tracking Recently Used Channels
As noted above, channel delay has largely been replaced with systems that use timestamps to ensure channels are merged appropriately. However, check your server’s S2S protocol documentation for more information on how they tackle this issue.
6.3 - Collisions And Channel Modes
The spec reads:
each other. Channel collisions (either legitimate or not) are
treated as inclusive events, meaning that the resulting channel has
for members all the users who are members of the channel on either
server prior to the connection.
While all members of the channels are joined, typically only one side’s channel membership prefixes/statuses (the side with the older channel) end up surviving the rejoin. This prevents malicious people from causing a server split, parting and rejoining the channel to become a chanop, then wreaking havoc when the channels merge back together.
However, how the server merges channels is related to the server’s S2S protocol. Check the S2S protocol documentation and code for the server you’re looking at to see how they’ve done it.
6.4 - Resource Exhaustion
Typically there are two resource exhaustion issues servers look to mitigate these days:
- Clients setting too many masks on a channel.
- Clients joining too many channels at once.
The number of masks clients can set on a channel is almost always restricted, and noted by the MAXLIST
RPL_ISUPPORT token sent to them when they join.
Clients usually have a maximum number of channels that they can join, noted by the CHANLIMIT
RPL_ISUPPORT token sent to them when they join.
7.1 - Access Control
The spec reads:
This mechanism can only be efficient and safe if the IRC servers have
an accurate way of authenticating user connections, and if users
cannot easily get around it. While it is in theory possible to
implement such a strict authentication mechanism, most IRC networks
(especially public networks) do not have anything like this in place
and provide little guaranty about the accuracy of the username and
hostname for a particular client connection.
While the username and hostname of a client often can’t be trusted, many (I’d even say most) networks these days do have user account registration through NickServ or some similar system. In addition, many servers let you explicitly control access to your channel by way of allowing specific accounts to join the channel (with the use of extbans).
7.2 - Channel Privacy
The spec reads:
its access control settings. This method has long been used by
individuals to "take over" channels by "illegitimately" gaining
channel operator status on the channel. The same method can be used
to find out the exact list of members of a channel, as well as to
eventually receive some of the messages sent to the channel.
As noted above, most S2S protocols work to prevent the malicious user from gaining channel operator credentials or similar. Channel ownership in the form of ChanServ also helps reduce the viability of ongoing disruption if a malicious actor does gain channel operator permissions.
7.3 - Anonymity
For better or for worse, this channel mode typically isn’t implemented in today’s servers.
RFC 2813
The protocol described in this specification isn’t used today. Well, to be specific, it is used as the basis of newer server-to-server (S2S) protocols like TS6 and P10, but isn’t useful on its’ own.
These days, most servers have either customised up or written their own S2S protocol. Look at your IRC server’s documentation for info on the S2S protocol it uses.
RFC 7194
2.2.2 - Client Certificate
This section deals with clients connecting to servers using TLS, and supplying a client certificate while connecting.
The section reads:
The certificate's Common Name should match the main IRC nickname.
If the network offers nick registration, this nick should be used.
If the network offers grouped nicks, the main nick or account name
should be used.
The client certificate’s common name isn’t really looked at in any way.
Servers only really look at a hashed signature (fingerprint) of the certificate, using it as an extra layer of authentication for operators or to authenticate to user accounts using SASL + CertFP (which just uses this certificate fingerprint).
Hardy's IRC RPL_ISUPPORT Numeric Definition Internet-Draft
On the whole, this specification is pretty much accurate and works well. There are a few tokens specified here which aren’t well-used these days, and some that are missing but should be here. The Modern docs has a slightly-updated description of the RPL_ISUPPORT numeric in these sections: 1, 2, 3, and 4.
3 - The RPL_ISUPPORT numeric
The spec reads:
counter this, a server MAY issue multiple RPL_ISUPPORT numerics. A
server MUST issue the RPL_ISUPPORT numeric after client registration
has completed. It MUST be issued after the RPL_WELCOME (XXX -
reference?) welcome and MUST be issued before any further commands
from the client are processed.
This is accurate, but a little imprecise. To be specific, the 001-004
numerics are the first numerics sent after connection registration has completed, followed by one or more RPL_ISUPPORT (005)
numerics. The RPL_ISUPPORT
numerics MUST come before either the RPL_ENDOFMOTD
/ ERR_NOMOTD
numerics.
The Client-To-Client Protocol (CTCP)
My advice on this specification can roughly be summed up as “go read this Internet-Draft that grawity and I wrote up instead”. Still, here are the sections of the original spec that have issues today.
LOW LEVEL QUOTING
The spec reads:
Even though messages to and from IRC servers cannot contain NUL, NL,
or CR, it still might be desirable to send ANY character (in so called
"middle level messages") between clients. In order for this to be
possible, those three characters have to be quoted. Therefore a quote
character is needed. Of course, the quote character itself has to be
quoted too, since it is in-band.
Quite simply, nothing does this. No clients actually implement this in reality. Ignore this entirely
TAGGED DATA
The spec reads:
The text part of a PRIVMSG or NOTICE might contain zero or more
extended messages, intermixed with zero or more chunks of non-extended
data.
In reality, there can be zero (0
) or one (1
). Clients just see whether the first character of incoming messages is a \001
(X-DELIM
), and if so, treat it as a CTCP message. Otherwise, assume it’s a normal message and display it to the user as such.
If you do insert more than one “extended message”, most clients won’t know what on earth you’re talking about. Avoid them.
CTCP LEVEL QUOTING
The spec reads:
In order to be able to send the delimiter X-DELIM inside an extended
data message, it has to be quoted. This introduces another quote
character (which differs from the low level quote character so it
won't have to be quoted yet again).
No. Just, no. Nothing does this. For the love of whatever spirit you subscribe to (or lack thereof), don’t implement this. It is unnecessary, and clients have decided, on the whole, to not actually follow the advice given here.
SED
The spec reads:
SED probably stands for something like "Simple Encryption D???". It is
used by clients to exchange encrypted messages between clients. A
message encoded by SED probably looks something like:
As you can probably guess from the use of the word ‘probably’ in this section, this isn’t documented or used today.
VERSION
The spec reads:
\001VERSION #:#:#\001
where the first # denotes the name of the client, the second # denotes
the version of the client, the third # the enviroment the client is
running in.
Some clients format their VERSION
values like this. A much larger number don’t, however. Treat the returned value as an opaque blob.
SOURCE
The spec reads:
\001SOURCE #:#:#\001
where the first # is the name of an Internet host where the client can
be gotten from with anonymous FTP the second # a directory names, and
the third # a space separated list of files to be gotten from that
directory.
These days, clients that implement this just link to their Github repo or similar.
ERRMSG
Honestly, a lot of clients don’t implement this or any sort of ERROR
CTCP messages. Avoid sending them in new clients.
DCC
These days:
- DCC implementations commonly also have the
RESUME
andACCEPT
commands. - IPv4 addresses can either be standard IP address strings (e.g.
127.0.0.1
) or the positive integer that is the IP address in network byte order (e.g.2130706433
), whereas IPv6 addresses are sent and accepted as address strings such as::1
. - Port
0
may be sent by a client when it wants the client receiving the request to open the DCC connection, to work around NAT restrictions.
However, DCC still doesn’t have any automatic or opportunistic forms of encryption, so that’s still accurate!
Acknowledgements
Thanks to everyone who’s written sane IRC specifications (including most of the above). IRC wouldn’t be here today without them, even if they have gotten a little old :)
Thanks to thommey for inspiring this page.