Skip to content

CNPJ (alphanumeric)

data specs/data/cnpj.kmd

Validation + format rules for the Brazilian CNPJ company identifier, including the RFB Instrução Normativa 2.229/2024 ALPHANUMERIC CNPJ that begins issuance July 2026. Date-versioned: legacy 14-digit numeric CNPJs stay valid forever; new ones may carry letters in the first 12 positions. The two check digits stay numeric and use the same mod-11 over an ASCII-based character value. Any Koder surface validating, storing, or masking a CNPJ MUST follow this.

When this spec applies

Primary triggers

All triggers

Specification body

Spec — CNPJ (alphanumeric)

Status: v0.1.0 — Draft. Promoted from the gov.br (DS Gov) parity scan (meta/docs/stack #098). Source: Receita Federal IN RFB nº 2.229/2024 (alphanumeric CNPJ, issuance from 2026-07).

R1 — Structure (date-versioned)

A CNPJ has 14 positions, displayed NN.NNN.NNN/NNNN-DD:

PositionsEra ≤ 2026-06 (legacy)Era ≥ 2026-07 (alphanumeric)
1–12 (base + branch)digits 0-9alphanumeric 0-9 and A-Z (uppercase)
13–14 (check digits DD)digits 0-9digits 0-9 (always numeric)

Both eras coexist permanently: legacy all-numeric CNPJs remain valid and are a strict subset of the alphanumeric rules. Never reject an existing numeric CNPJ because it lacks letters, and never reject a well-formed alphanumeric CNPJ because it has letters.

R2 — Character value (for the check digits)

Each of the first 12 positions contributes a numeric value:

value(c) = ASCII(c) − 48

So '0'..'9' → 0..9 and 'A'..'Z' → 17..42. This is the official RFB rule and makes the legacy numeric algorithm a special case.

R3 — Check-digit algorithm (mod 11)

Identical to the legacy CNPJ algorithm, applied over value(c):

  1. DV1: weight positions 1–12 by [5,4,3,2,9,8,7,6,5,4,3,2]; sum value(c)·weight; r = sum mod 11; DV1 = r < 2 ? 0 : 11 − r.
  2. DV2: weight positions 1–13 (the 13th being DV1) by [6,5,4,3,2,9,8,7,6,5,4,3,2]; same r/DV rule.

Positions 13–14 must equal DV1/DV2. Uppercase before computing (lowercase letters are normalized to uppercase, R4).

R4 — Normalization

  • Strip the mask punctuation (., /, -) before validating/storing.
  • Uppercase any letters; reject characters outside [0-9A-Z] after stripping.
  • Persist the canonical 14-character unmasked value (per specs/data/masks.kmd R "persist without mask"); apply the mask only for display/input.

R5 — Input & masking

  • The cnpj field type accepts alphanumeric input in the alphanumeric era: inputmode is not numeric (letters are allowed) — use a text input with an uppercasing + alnum filter; the visual mask NN.NNN.NNN/NNNN-DD still applies (see specs/data/masks.kmd, whose numeric-only assumption for cnpj is superseded here for the alphanumeric era).
  • Reject-on-blur with a specific message (specs/errors/user-facing-messages.kmd): "Invalid CNPJ".

R6 — Accessibility & i18n

  • The CNPJ format is BR-fixed and locale-independent (the mask never changes with UI locale), per specs/data/masks.kmd.
  • Error/label strings localize per specs/i18n/contract.kmd; the format itself does not.
  • The field announces its expected format up front, not only on error.

Não-escopo

  • CPF and CEP (their own rules; CPF stays 11 numeric digits).
  • The numeric presentation mask mechanics (specs/data/masks.kmd).
  • Server-side existence/active-status lookup at Receita Federal (a product integration, not a format rule).

References