IRCv3.2 Message Tags

Copyright © 2012-2014 Alexey Sokolov <>

Copyright © 2012 Stéphan Kochen <>

Copyright © 2012 Kyle Fuller <>

Unlimited redistribution and modification of this document is allowed provided that the above copyright notice and this permission notice remains intact.

Updated by: Message Tags 3.3

Additional optional tags are added to the start of each message.

The message pseudo-BNF, as defined in RFC 1459, section 2.3.1 is extended to look as follows:

<message>       ::= ['@' <tags> <SPACE>] [':' <prefix> <SPACE> ] <command> <params> <crlf>
<tags>          ::= <tag> [';' <tag>]*
<tag>           ::= <key> ['=' <escaped value>]
<key>           ::= [ <vendor> '/' ] <sequence of letters, digits, hyphens (`-`)>
<escaped value> ::= <sequence of any characters except NUL, CR, LF, semicolon (`;`) and SPACE>
<vendor>        ::= <host>

Every message tag is enabled by a capability. The same capability can be used for several tags, if these tags are intended to be used together.

Every tag can have own rules when it can be used: from client to server only, from server to client only, or in both directions.

Server MUST NOT add a tag to messages, if client didn’t request the capability which enables the tag using CAP REQ. Server MUST NOT add a tag to messages before replying to client’s CAP REQ with CAP ACK. If client requested a capability, which enables one or more message tags, client MUST be able to parse the tags syntax.

Client MUST NOT add a tag to messages before server replies to client’s CAP REQ with CAP ACK. If server accepted the capability request with CAP ACK, server MUST be able to parse the tags syntax.

Client and server MAY parse the tags even without any capabilities enabled. They SHOULD ignore tags of capabilities which are not enabled.

This ensures back-compatibility with standard IRC protocol, because no capabilities are enabled by default, and therefore messages can’t have any tags unless client explicitly enables such capabilities.

Size limit for the message tags MUST be 512 bytes, including @ and the trailing space characters, leaving 510 bytes for tags themselves. So the total size of a message becomes limited by 1024 bytes: 512 bytes for message tags, and 512 bytes for the rest as specified by RFC 1459.

If a message has multiple tags, order of the tags MUST NOT matter. Two or more tags with the same key MUST NOT appear on the same message.

Escaping values

The mapping between characters in tag values and their representation in <escaped value> MUST be this:

Character Sequence in <escaped value>
; (semicolon) \: (backslash and colon)
\ \\
CR \r
LF \n
all others the character itself

Reason: more common URL-escaping eats more space, while IRC message’s length is very limited. Also having semicolon as \: makes it easy to split the <tags> string by ; first.

If a lone \ exists at the end of an escaped value (with no escape character following it), then there SHOULD be no output character. For example, the escaped value test\ should unescape to test.

Rules for naming message tags

The full tag name MUST be treated as an opaque identifier.

There are two tag namespaces:


Names which contain a slash character (/) designate a vendor-specific tag namespace. These names are prefixed by a valid DNS domain name.

For example:

In cases where the prefix contains non-ASCII characters, punycode MUST be used, e.g.

Vendor-Specific tags should be submitted to the IRCv3 working group for consideration.


Names for which a corresponding document sits in the IRCv3 Extension Registry.

Names in the IRCv3 Extension Registry are reserved for your tag.

The IRCv3 Working Group reserves the right to reuse names which have not been submitted to the registry. If you do not wish to submit your tag then you MUST use a vendor-specific name (see above).


Message with 0 tags:

:nick! PRIVMSG me :Hello

Message with 3 tags:

@aaa=bbb;ccc; :nick! PRIVMSG me :Hello


Previous versions of this spec did not specify that the full tag name MUST be parsed as an opaque identifier. This was added to improve client resiliency.

Previous versions of this spec did not specify how to handle trailing backslashes with no escape character. This was added to help consistency across implementations.