BabylonJS/Babylon.js · error · Error
Not a valid binary FBX file
Error message
Not a valid binary FBX file
What it means
parseBinaryFBX validates the file begins with the exact 21-byte magic string `Kaydara FBX Binary \0`. If the first bytes differ, the input is not a binary FBX file, and parsing cannot proceed — the parser throws immediately before reading the header/version.
Source
Thrown at packages/dev/loaders/src/FBX/parsers/fbxBinaryParser.ts:19
/* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */
import { type FBXDocument, type FBXNode, type FBXProperty, type FBXPropertyType } from "../types/fbxTypes";
import { inflateZlib } from "./zlibInflate";
const FBX_MAGIC = "Kaydara FBX Binary \0";
const HEADER_SIZE = 27; // 21 magic + 2 padding + 4 version uint32
/**
* Parse a binary FBX file into an FBXDocument.
* Supports FBX versions 7.0–7.7 (v7.5+ uses 64-bit node headers).
*/
export function parseBinaryFBX(buffer: ArrayBuffer): FBXDocument {
const view = new DataView(buffer);
const bytes = new Uint8Array(buffer);
// Validate magic
const magic = decodeASCII(bytes, 0, 21);
if (magic !== FBX_MAGIC) {
throw new Error("Not a valid binary FBX file");
}
if (buffer.byteLength < HEADER_SIZE) {
throw new Error("Truncated binary FBX header");
}
const version = view.getUint32(23, true);
// v7.5+ uses 64-bit offsets in node records
const is64Bit = version >= 7500;
const nodes: FBXNode[] = [];
let offset = HEADER_SIZE;
while (offset < buffer.byteLength) {
const result = parseNode(view, bytes, offset, is64Bit, buffer.byteLength);
if (result === null) {
break; // null sentinel node
}
nodes.push(result.node);
View on GitHub (pinned to 0592b347b8)
Solutions
- Check the first bytes of the file — if it starts with `Kaydara FBX Binary` it is binary; if it starts with text like `; FBX` use the ASCII parser
- If the file starts with `PK`, it is a ZIP — unzip it to get the real FBX
- Re-export the asset as FBX binary from the DCC tool
- Verify the file was not truncated/transformed in transit (e.g. text-mode transfer corrupting bytes)
Example fix
// before loader.parse(fbxBytes); // bytes are actually ASCII FBX // after const isBinary = new TextDecoder().decode(bytes.slice(0, 21)) === "Kaydara FBX Binary "; if (isBinary) loader.parse(bytes); else loader.parse(text);
Defensive patterns
Strategy: validation
Validate before calling
const MAGIC = "Kaydara FBX Binary \0";
function isBinaryFbx(buf) {
if (buf.byteLength < 27) return false;
let s = "";
const b = new Uint8Array(buf, 0, 21);
for (const x of b) s += String.fromCharCode(x);
return s === MAGIC;
}
if (!isBinaryFbx(buffer)) throw new Error("Not binary FBX — use the ASCII parser or convert the file"); Type guard
function isBinaryFbxBuffer(buf) {
if (!(buf instanceof ArrayBuffer) || buf.byteLength < 27) return false;
const magic = String.fromCharCode(...new Uint8Array(buf, 0, 21));
return magic === "Kaydara FBX Binary \0";
} Try / catch
try {
const doc = parseBinaryFBX(buffer);
} catch (e) {
if (e.message === "Not a valid binary FBX file") {
// sniff: PK => zip, '<' or '; FBX' => ascii/xml; route accordingly
console.error("Wrong format fed to binary FBX parser");
} else throw e;
} Prevention
- Route files by sniffing the 21-byte magic before selecting ASCII vs binary parser
- Watch for PK zip signatures — some '.fbx' payloads are zips
- Keep magic/HEADERSIZE checks before any DataView reads
- Validate uploads at ingest with the same magic check
When it happens
Trigger: Calling the loader's ArrayBuffer parse path (via `_parseFromArrayBuffer`/`doc`) with bytes that are ASCII FBX, a ZIP archive (often mistakenly called .fbx), an OBJ/DAE file, or any non-FBX binary.
Common situations: Feeding ASCII FBX into the binary parser (or vice versa); renaming a .zip (FBX 2020+ default is actually binary but some pipelines store zipped FBX) or .dae to .fbx; corrupted uploads where the magic bytes are lost.
Related errors
- Truncated binary FBX header
- Invalid FBX node end offset ${endOffset} at offset ${offset}
- Invalid FBX property list length for node '${name}' at offse
- Invalid FBX child node end offset ${child.endOffset} at offs
- Unknown FBX property type: '${typeCode}' at offset ${offset
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/1b69fb60d2ef8726.
Report an issue: GitHub.