# BR-29: Fix an invoicing period that ends before it starts

When the document-level invoicing period gives both dates, `cbc:EndDate` must fall on the same day as `cbc:StartDate` or later.

- Layer: EN 16931
- Severity: fatal (the document is invalid)
- Topics: Core fields
- Official definition: https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-29/
- Explanation last updated: 2026-09-24

## The short answer

`BR-29` fails when the `cac:InvoicePeriod` beneath the document root has a `cbc:EndDate` earlier than its `cbc:StartDate`. Write the first day of the period the invoice covers as the start date and the last day as the end date, taking both from the billing record.

A one-day period is allowed: start and end may be the same date. The rule objects only when the end comes first.

## What the rule checks

The rule reads the document-level `cac:InvoicePeriod`, and only when it contains both a `cbc:StartDate` and a `cbc:EndDate`. A period with just one of the two dates is not compared at all.

The two values are compared as calendar dates, not as text. The end date passes when it is the same day as the start date or any later day; when tried, a period starting and ending on 2026-08-01 was accepted.

Line periods are outside this rule. When tried, a line `cac:InvoicePeriod` with its dates swapped reported `BR-30`, the line-level counterpart, and not `BR-29`.

A value that is not a date at all, such as `31/08/2026`, fails the XSD layer, and the business rules, this one included, are then skipped.

| Term | Meaning | UBL element |
|---|---|---|
| BT-73 | Invoicing period start date | `cac:InvoicePeriod/cbc:StartDate` |
| BT-74 | Invoicing period end date | `cac:InvoicePeriod/cbc:EndDate` |

## How an integration ends up here

Possible causes, from the shape of the rule rather than from measured usage:

- The start and end values are mapped to each other's elements in the export template.
- Dates held as text are parsed with the day and month the wrong way round: a period from 5 January to 2 February, stored as 05/01/2026 and 02/02/2026, becomes 1 May to 2 February when read month first.
- The end date is computed from the start date plus a duration, and a cancelled or reversed subscription produces a zero or negative duration.
- A credit note copies the period of the invoice it corrects but fills the start from the old end date and the end from the old start date.

## How to fix it

1. Find where the invoicing period comes from: the subscription term, the service dates or the billing run.
2. Write the first day of that period to `cac:InvoicePeriod/cbc:StartDate` and the last day to `cac:InvoicePeriod/cbc:EndDate`, both as `YYYY-MM-DD`.
3. If dates arrive as text, parse them with an explicit format that matches the source, never with a locale default.
4. If the source record itself is wrong, correct it there. Swapping the two values in the XML is only right when they were simply written to the wrong elements.
5. Check any line periods against the corrected document period: Peppol rejects a line period that starts before it (`PEPPOL-EN16931-R110`) or ends after it (`PEPPOL-EN16931-R111`).

## Before and after

These are fragments, not complete documents. The complete synthetic documents they come from are linked below.

Fragment of the failing invoice: the period runs from 31 August back to 1 August

```xml
<cbc:BuyerReference>BUYER-REF-001</cbc:BuyerReference>
<cac:InvoicePeriod>
  <cbc:StartDate>2026-08-31</cbc:StartDate>
  <cbc:EndDate>2026-08-01</cbc:EndDate>
</cac:InvoicePeriod>
```

Fragment of the corrected invoice: the period starts on 1 August and ends on 31 August

```xml
<cbc:BuyerReference>BUYER-REF-001</cbc:BuyerReference>
<cac:InvoicePeriod>
  <cbc:StartDate>2026-08-01</cbc:StartDate>
  <cbc:EndDate>2026-08-31</cbc:EndDate>
</cac:InvoicePeriod>
```

The two dates have changed places: the corrected invoice starts the period on 2026-08-01 and ends it on 2026-08-31. Nothing else differs, and `BR-29` is the only finding the failing document reports; the XSD and Peppol layers pass because each date is well formed on its own and the invoice has no line periods.

### What the validator reported

- The failing invoice reports **BR-29**. The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-29-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/finance/rule-examples/invoice-period-valid.xml)

Recorded on phive 12.1.0 / phive-rules-peppol 4.5.6 / Saxon-HE 12.10, the engine behind the free validator, using synthetic data. A recorded result is regression evidence for these documents; it is not a certification.

## Where it applies

- Applies to UBL `Invoice` and `CreditNote` alike. When tried, a credit note with the same reversed period reported `BR-29` at its `cac:InvoicePeriod`.
- It is an EN 16931 rule and is reported in the EN 16931 layer.
- Line periods have their own rule, `BR-30`, which makes the same comparison inside each `cac:InvoiceLine` or `cac:CreditNoteLine`.
- A date written with a time zone suffix, such as `2026-08-31Z`, passes the XSD but is rejected in the Peppol layer by `PEPPOL-EN16931-F001`.

## Related rules

- [BR-CO-19 requires at least one date in an invoicing period, which this rule then keeps in order](https://ironfang.uk/docs/finance/rules/BR-CO-19.md)
- [PEPPOL-EN16931-R110 checks that no line period starts before this invoicing period](https://ironfang.uk/docs/finance/rules/PEPPOL-EN16931-R110.md)
- [PEPPOL-EN16931-F001 rejects period dates that are not plain YYYY-MM-DD values](https://ironfang.uk/docs/finance/rules/PEPPOL-EN16931-F001.md)

## Scope and source

Written for Peppol BIS Billing 3.0.21 (May 2026), EN 16931 1.3.16, as applied to UBL 2.1 Invoice and CreditNote documents. Other profiles, syntaxes and releases can define this identifier differently. Guidance version 2026-09-24.1: source checked 2026-09-24, explanation last updated 2026-09-24.

[The official definition of BR-29](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-29/) carries the normative wording and test. This page is our explanation of it, not a copy.

Guidance does not change the engine verdict. Fixing this finding does not mean the document passes every layer, and validation does not certify legal or tax compliance or transmit a document over Peppol.

## Links

- [This rule as a web page](https://ironfang.uk/docs/finance/rules/BR-29)
- [Free Peppol invoice validator](https://ironfang.uk/tools/peppol-validator)
- [Rule index](https://ironfang.uk/docs/finance/rules.md)
- [Ironfang Finance API docs](https://ironfang.uk/docs/finance)
- The same rule is available to MCP clients as the tool `finance.rule.get` on https://mcp.ironfang.uk/mcp
