Der CAA-Record-Typ erlaubt Domaininhabern festzulegen, welche Zertifizierungsstelle Zertifikate für eine Domain ausstellen darf. Er wurde mit RFC6844 eingeführt und später durch RFC8659 überarbeitet. Der Record enthält ein Flags-Byte: Bit 0 ist das Issuer-Critical-Flag, die Bits 1 bis 7 sind reserviert.

va/caa.go (LetsEncrypt Boulder)
default:
 // The critical flag is the bit with significance 128. However, many CAA
 // record users have misinterpreted the RFC and concluded that the bit
 // with significance 1 is the critical bit.
 if (caaRecord.Flag & (128 | 1)) != 0 {
 criticalUnknown = true
 }

Der Haken: Nach den Konventionen aus RFC1035 ist Bit 0 das höchstwertige Bit. Wer das Critical-Flag setzen will, muss also 128 schreiben, binär 10000000. Viele Nutzer lasen die Spezifikation und folgerten, der Wert müsse 1 lauten, binär 00000001. Das setzt Bit 7, das niederwertigste Bit, das reserviert ist und ignoriert werden soll.

RFC8659 fügt eine klärende Nummerierungsregel hinzu: 128 aktiviert das Critical-Bit, 1 nicht. Die Klarstellung kam zu spät. Die Fehlinterpretation hatte sich bereits in unzähligen DNS-Zonen verbreitet.

Das bringt Zertifizierungsstellen wie LetsEncrypt in ein Dilemma. Die Spezifikation verlangt, dass eine CA die Ausstellung verweigert, wenn ein unbekannter Property-Tag das Critical-Bit trägt. Doch ein großer Teil der Nutzer hat das falsche Bit gesetzt. LetsEncrypts Boulder-Code löst den Konflikt, indem er die fehlerhaften Daten akzeptiert: Die Funktion filterCAA in va/caa.go prüft beide Bits, und der Kommentar behandelt das falsch gesetzte Bit als inoffiziellen Ersatz für das echte Critical-Bit.

Autor Remy Porter schließt mit einer Designfrage. Bitmasken erlauben die kompakte Kombination von Werten über boolesche Operationen, aber Menschen machen dabei ständig Fehler. Wenn ohnehin sieben von acht Bits reserviert sind, wäre ein einfaches Flag womöglich die klügere Wahl gewesen.