Skip to content

What Is a Byte Order Mark (BOM)?

Sep 9, 2026 · Formats & Standards

A byte order mark (BOM) is the Unicode character U+FEFF placed at the very beginning of a text stream to signal the encoding and, for UTF-16 and UTF-32, the byte order (endianness) of the data that follows. In UTF-16 and UTF-32 the BOM is genuinely useful because those encodings can store their code units most-significant-byte-first or least-significant-byte-first. In UTF-8 the BOM carries no byte-order information at all and acts only as an optional signature, which is why an unexpected BOM is one of the most common sources of mysterious parsing and output bugs.

Key takeaways

  • The BOM is the code point U+FEFF, named ZERO WIDTH NO-BREAK SPACE, written at the start of a stream.
  • In UTF-16 the bytes are FE FF for big-endian and FF FE for little-endian; UTF-8’s signature is EF BB BF.
  • UTF-8 has no endianness, so a UTF-8 BOM is optional and usually unwanted on the web and Unix.
  • A stray BOM breaks JSON parsing, PHP header output, shell scripts, and string comparisons.
  • Detect a BOM by inspecting the first few raw bytes; remove it by re-saving without BOM or stripping the leading code point.

What exactly is the byte order mark character?

The BOM is a single Unicode code point, U+FEFF. Its formal name is ZERO WIDTH NO-BREAK SPACE, and when it appears anywhere other than the first position it is treated as invisible zero-width text. Only at the very start of a file or stream does it take on its special meaning as a byte order mark.

Unicode deliberately left the mirror code point U+FFFE permanently unassigned. That way a decoder reading a UTF-16 stream can look at the first two bytes: if it sees the valid character U+FEFF it has the byte order right, and if it sees the impossible U+FFFE it knows the bytes are swapped and it must flip endianness.

Why does byte order matter for UTF-16 and UTF-32?

UTF-16 stores text in 16-bit code units, and UTF-32 in 32-bit units. Any unit larger than one byte must be laid out in memory or on disk in some order. Big-endian writes the most significant byte first; little-endian writes the least significant byte first. The same code unit therefore produces different byte sequences on different platforms, and a reader that assumes the wrong order will decode garbage.

The BOM solves this by encoding U+FEFF using the file’s actual byte order, so the reader can infer endianness from the first unit. UTF-8, by contrast, is defined as a sequence of individual bytes with a fixed order, so there is nothing for a BOM to disambiguate.

What are the BOM byte signatures for each encoding?

Each Unicode encoding form produces a distinctive leading byte sequence when it encodes U+FEFF. Recognizing these lets you sniff an unknown file’s encoding.

Encoding BOM bytes Byte order
UTF-8 EF BB BF Not applicable (signature only)
UTF-16 BE FE FF Big-endian
UTF-16 LE FF FE Little-endian
UTF-32 BE 00 00 FE FF Big-endian
UTF-32 LE FF FE 00 00 Little-endian

Note the ambiguity: a UTF-16 LE BOM (FF FE) is also the prefix of a UTF-32 LE BOM (FF FE 00 00). Robust detectors check the longer UTF-32 signatures before the shorter UTF-16 ones.

Should I use a BOM in UTF-8?

For most modern work the answer is no. UTF-8 is the default encoding of the web, JSON, and Unix, and those ecosystems expect files without a BOM. Some Windows tools historically wrote a UTF-8 BOM as an encoding hint, which is why files created on Windows sometimes carry an invisible EF BB BF prefix that surprises Unix tooling.

Add a UTF-8 BOM only when a consumer you cannot change specifically requires it, such as certain spreadsheet importers that use it to recognize UTF-8 CSV files. Otherwise, save as UTF-8 without BOM.

What bugs does a stray BOM cause?

Because a leading BOM is invisible in most editors, the failures it causes look baffling until you inspect the raw bytes.

  • PHP output: a BOM before the opening tag is sent to the browser as three bytes, so any later call that sets headers fails with a headers already sent error, and pages gain a stray blank line.
  • JSON parsing: many parsers reject a document that begins with a BOM, since RFC 8259 forbids emitting one.
  • Shell scripts: a BOM before the shebang line prevents the kernel from recognizing the interpreter, producing a confusing not found error.
  • String comparison: a configuration value read from a BOM-prefixed file gains an invisible first character, so an equality or key lookup silently fails.
  • Concatenation: joining several UTF-8 files that each start with a BOM scatters stray marks through the middle of the result.

How do I detect a BOM programmatically?

The reliable approach is to read the first few bytes of the raw stream before any text decoding and compare them against the known signatures. Reading as decoded text can hide the BOM as a single character or strip it depending on the platform.

read first 4 bytes as B0 B1 B2 B3
if B0==FF and B1==FE and B2==00 and B3==00 -> UTF-32 LE
if B0==00 and B1==00 and B2==FE and B3==FF -> UTF-32 BE
if B0==EF and B1==BB and B2==BF        -> UTF-8 with BOM
if B0==FE and B1==FF                   -> UTF-16 BE
if B0==FF and B1==FE                   -> UTF-16 LE
else                                   -> no BOM detected

Always test the longer UTF-32 signatures first so a UTF-32 LE file is not misread as UTF-16 LE.

How do I remove a BOM safely?

There are two dependable strategies:

  1. In an editor: use the encoding menu to re-save the file as UTF-8 without BOM. Most modern editors expose this as an explicit choice separate from plain UTF-8.
  2. Programmatically: after decoding the bytes to text, strip a single leading U+FEFF if present. If you operate on raw UTF-8 bytes, remove the three-byte EF BB BF prefix.

When decoding, prefer an encoding label that consumes the BOM for you. For example, decoding explicitly as UTF-8-with-signature or UTF-16 (endianness auto-detected from the BOM) lets the decoder discard the mark rather than leaving it in your string.

A note on interoperability

When you generate files for other systems, be explicit about whether you emit a BOM and document it. A producer that quietly adds a BOM and a consumer that does not strip one is the archetypal cause of these bugs, and the fix is almost always to standardize on UTF-8 without a BOM everywhere you can.

Frequently asked questions

What Unicode character is the BOM?

It is U+FEFF, formally named ZERO WIDTH NO-BREAK SPACE. When it appears at the very start of a file or stream it is interpreted as a byte order mark rather than as text.

Should I add a BOM to UTF-8 files?

Generally no. UTF-8 has no byte order to signal, and a leading BOM breaks many tools. Most web and Unix toolchains expect UTF-8 without a BOM.

Why does my PHP page output a blank line or break headers?

A UTF-8 BOM at the start of a PHP file is emitted as three bytes before any code runs, producing stray output and the classic headers already sent error. Save the file as UTF-8 without BOM.

Is a BOM allowed in JSON?

RFC 8259 says JSON text must not be prefixed with a BOM, though parsers may choose to ignore one. For maximum compatibility, never emit JSON with a BOM.

How do I tell UTF-16 big-endian from little-endian?

By the BOM bytes: FE FF means big-endian, FF FE means little-endian. Without a BOM you must know the endianness from an external source.

Does the BOM count as a character in string length?

If it is not stripped on read, yes. A leading U+FEFF becomes an invisible first character that can break equality checks, parsing, and keys.

How do I remove a BOM?

Re-save the file as UTF-8 without BOM in your editor, or strip the leading bytes programmatically, for example by removing a leading U+FEFF after decoding.

Frequently asked questions

What Unicode character is the BOM?

It is U+FEFF, formally named ZERO WIDTH NO-BREAK SPACE. When it appears at the very start of a file or stream it is interpreted as a byte order mark rather than as text.

Should I add a BOM to UTF-8 files?

Generally no. UTF-8 has no byte order to signal, and a leading BOM breaks many tools. Most web and Unix toolchains expect UTF-8 without a BOM.

Why does my PHP page output a blank line or break headers?

A UTF-8 BOM at the start of a PHP file is emitted as three bytes before any code runs, producing stray output and the classic headers already sent error. Save the file as UTF-8 without BOM.

Is a BOM allowed in JSON?

RFC 8259 says JSON text must not be prefixed with a BOM, though parsers may choose to ignore one. For maximum compatibility, never emit JSON with a BOM.

How do I tell UTF-16 big-endian from little-endian?

By the BOM bytes: FE FF means big-endian, FF FE means little-endian. Without a BOM you must know the endianness from an external source.

Does the BOM count as a character in string length?

If it is not stripped on read, yes. A leading U+FEFF becomes an invisible first character that can break equality checks, parsing, and keys.

How do I remove a BOM?

Re-save the file as UTF-8 without BOM in your editor, or strip the leading bytes programmatically, for example by removing a leading U+FEFF after decoding.

Contact: contact@quikconsolecom.net