encoding.bom
Byte Order Mark (BOM) at file start
AT rejects SAF-T files that start with a UTF-8 or UTF-16 BOM.
What is a BOM
A Byte Order Mark is a 2- or 3-byte signature at the very start of a text file that signals which Unicode encoding the file uses. You can't see it in most editors, which is what makes it hard to find:
| Encoding | BOM bytes | What it means for a SAF-T file |
|---|---|---|
| UTF-8 | EF BB BF | Strip the 3 bytes; also check the encoding declaration. |
| UTF-16 BE | FE FF | The whole file is UTF-16: it has to be converted, not just trimmed. |
| UTF-16 LE | FF FE | Same as above. Typical of files saved by Windows tools as "Unicode". |
Why AT rejects BOMs
AT expects SAF-T (PT) files in Windows-1252, which has no BOM. The schema and AT's intake parser expect the first byte of the file to be the < of the XML declaration, not a Unicode signature.
When a BOM is present, the XML may still open fine in a browser or your ERP, but the file is rejected at intake without a useful error. See what AT's error messages mean for the messages you might see.
What the start of the file should look like
A correct SAF-T (PT) file starts directly with the XML declaration:
<?xml version="1.0" encoding="Windows-1252"?>
<AuditFile xmlns="urn:OECD:StandardAuditFile-Tax:PT_1.04_01">
In a hex editor, the first bytes are 3C 3F 78 6D 6C (<?xml). With a UTF-8 BOM they are EF BB BF 3C 3F.
How a BOM gets there
- Opening the export in Notepad and saving it again as "UTF-8 with BOM" (older Windows default) or "Unicode" (UTF-16).
- Some ERPs and report tools prepend a BOM when exporting Unicode-aware XML.
- Converting the file with a tool that adds a signature, or merging files with a script that writes one.
How to check your file
Look at the first three bytes:
# Linux / macOS
head -c 3 my.xml | xxd
# Windows PowerShell
Format-Hex my.xml | Select-Object -First 1
If you see EF BB BF, FF FE or FE FF, the file has a BOM. Or upload the file to SAFTCheck, which checks this on every upload.
How to fix
UTF-8 BOM: remove the first 3 bytes; the rest of the file stays unchanged.
# Linux / macOS
sed -i '1s/^\xEF\xBB\xBF//' my.xml
UTF-16 BOM: removing the bytes is not enough, because every character in the file is 2 bytes. Convert the whole file to Windows-1252, then make sure the declaration says encoding="Windows-1252":
# Linux / macOS
iconv -f UTF-16 -t WINDOWS-1252 my.xml > my-fixed.xml
On Windows without command-line tools: in Notepad++, use Encoding, then "Convert to ANSI", and save. Avoid re-saving with Windows Notepad, which is often how the BOM got there in the first place.
The best long-term fix is in the ERP export settings, so the next month's file comes out right.
What SAFTCheck does
The finding appears as encoding.bom with the location "File offset 0" and the BOM type (UTF-8, UTF-16 BE or UTF-16 LE). "Auto-fix and download" strips a UTF-8 BOM and converts UTF-16 files to Windows-1252, along with any other encoding fixes the file needs. The fixed file is validated again before you download it.
A blank line or spaces before <?xml cause the same kind of silent rejection; the auto-fix removes those too.
Related
- XML encoding declaration (Windows-1252): the broader encoding requirement.
- How to fix the SAF-T UTF-8 encoding error in Portugal