AttestwireRule referenceBR-03

BR-03 An invoice must have an issue date

noun · EN 16931 · fatal · BT-2

an invoice that doesn’t say when it happened.

Your invoice was refused because it has no issue date. Every invoice needs the date it was issued, written as a plain calendar date such as 2026-08-09, and this is a one-field fix. In the standard the issue date is field 2, written BT-2, and BR-03 is the rule that checks it.

Business term
BT-2 — Invoice issue date
Severity
fatal
Applies to
All profiles

The fix

Put the issue date on the invoice as a plain calendar date string, issueDate: "2026-08-09". Format it once, at the edge of your system, and pass the string. The usual cause of a missing issue date is a Date object, or a Timestamp from your database driver, arriving where a string was expected and serialising to something the check reads as absent.

Convert with something that gives you the calendar date in your timezone rather than UTC, or an invoice issued late on the last day of a month can land in the wrong VAT period.

What the rule requires

The invoice needs the date you issued it, written as a calendar date in the form 2026-08-09 (ISO 8601). No time, no timezone, no offset. In business-term language that is BT-2; in UBL the element is cbc:IssueDate and its type is xs:date, which has nowhere to put the rest of a timestamp.

Three dates get mixed up here more than any others. BT-2 is when you issued the invoice. BT-72 is when the goods or services were delivered. BT-7 is the VAT point, the date the tax becomes chargeable, which national law sometimes puts somewhere else. They are often the same date, and they are never the same field.

Our input check fires when issueDate is missing, empty or only whitespace.

An Invoice shall have an Invoice issue date (BT-2).

BR-03 — EN 16931-1 business rules, as published in the Peppol BIS Billing 3.0 rule tables

Failing and passing

Fails — issueDate is absent
validateInput({
  profile: "en16931",
  invoiceNumber: "2026-000142",
  // issueDate omitted        <- BR-03
  currency: "EUR",
  seller: { /* ... */ },
  buyer:  { /* ... */ },
  lines:  [ /* ... */ ],
});
// -> { valid: false, errors: [ { rule: "BR-03", ... } ] }
Passes
validateInput({
  profile: "en16931",
  invoiceNumber: "2026-000142",
  issueDate: "2026-08-09",   // a plain calendar date, as a string
  currency: "EUR",
  seller: { /* ... */ },
  buyer:  { /* ... */ },
  lines:  [ /* ... */ ],
});
// -> { valid: true, errors: [] }

Why it exists

Almost everything downstream is measured from the issue date. It decides which VAT period the invoice falls into, which is the number your accountant reconciles against. It starts the payment clock, so “30 days net” means nothing without it. And it is the date a tax authority uses to work out which version of the rules applied to the supply.

A document with no issue date has no point in time to attach it to.

What the library returns

The full error returned by @attestwire/en16931. It includes the rule ID, affected field and suggested correction. Developers can use this object in their application:

TeachingError
{
  "rule": "BR-03",
  "field": "BT-2",
  "severity": "fatal",
  "message": "An invoice must have an issue date (BT-2). The issue date fixes the VAT period the invoice falls into and starts the payment clock.",
  "fix": "Set issueDate to the date you issued the document, as an ISO 8601 calendar date (\"YYYY-MM-DD\"). UBL forbids a time component here.",
  "example": "\"issueDate\": \"2026-08-09\"",
  "xpath": "/ubl:Invoice/cbc:IssueDate",
  "docsUrl": "https://attestwire.com/rules/BR-03"
}

xpath is always a UBL path. On a CII invoice, look for the matching CII field instead.

How our check differs

This check is about presence only. It does not ask whether the date is sensible: an invoice issued in 1970, or dated three years into the future, passes here. Nothing in EN 16931 tests that either, so this is the rule agreeing with the standard rather than a gap.

Whether the value is readable is a separate finding of ours.

Hand us "2026-13-01" and BR-03 stays quiet, because the field is present, while ATW-DATE-NOT-A-CALENDAR-DATE reports that there is no thirteenth month. Hand us "09/08/2026" and you get both: the shape is wrong enough that the field reads as unset. That id begins ATW- because it is ours, not the regulation’s; an official validator rejects the same document one step earlier, at XML Schema validation.

See also: BR-02 — an invoice must have an invoice number; ATW-DATE-NOT-A-CALENDAR-DATE — when the date is present but unreadable.