BabylonJS/Babylon.js · error · Error

Required extension ${name} is not available

Error message

Required extension ${name} is not available

What it means

The glTF asset lists an extension in its 'extensionsRequired' array, but no registered loader extension with that name is available (or it is not enabled). Since 'extensionsRequired' means the client MUST support the extension to render the asset, the loader aborts rather than produce a broken result.

Source

Thrown at packages/dev/loaders/src/glTF/2.0/glTFLoader.pure.ts:736

                        return extension;
                    })()
                );
            }
        });

        this._extensions.push(...(await Promise.all(extensionPromises)));

        this._extensions.sort((a, b) => (a.order || Number.MAX_VALUE) - (b.order || Number.MAX_VALUE));
        this._parent.onExtensionLoadedObservable.clear();

        if (this._gltf.extensionsRequired) {
            for (const name of this._gltf.extensionsRequired) {
                const available = this._extensions.some((extension) => extension.name === name && extension.enabled);
                if (!available) {
                    if (this.parent.extensionOptions[name]?.enabled === false) {
                        throw new Error(`Required extension ${name} is disabled`);
                    }
                    throw new Error(`Required extension ${name} is not available`);
                }
            }
        }
    }

    private _createRootNode(): INode {
        if (this._parent.customRootNode !== undefined) {
            this._rootBabylonMesh = this._parent.customRootNode;
            return {
                _babylonTransformNode: this._rootBabylonMesh === null ? undefined : this._rootBabylonMesh,
                index: -1,
            };
        }
        this._babylonScene._blockEntityCollection = !!this._assetContainer;
        const rootMesh = new Mesh("__root__", this._babylonScene);
        this._rootBabylonMesh = rootMesh;
        this._rootBabylonMesh._parentContainer = this._assetContainer;
        this._babylonScene._blockEntityCollection = false;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Import and register the required extension loader (e.g. GLTFLoaderDracoCompression, GLTFLoaderMeshoptCompression, GLTFLoader KhronosTextureContainer2) before loading
  2. Provide the necessary decoder/decoder binaries (Draco decoder URL, meshopt decoder, KTX2 decoder) via loader options
  3. Re-export the asset without the compression/extension if the runtime cannot support it
  4. Check the asset's extensionsRequired array and compare with the enabled this._extensions list

Example fix

// before
const loader = new GLTFLoader();
const data = await loader.loadAsync("/scenes/model.glb"); // throws: KHR_draco_mesh_compression not available
// after
import { GLTFLoaderDracoCompression } from "loaders/glTF/2.0/Extensions/DRACOLoader";
const loader = new GLTFLoader();
loader.registerPlugin(new GLTFLoaderDracoCompression(loader));
loader.dracoDecoder = { url: "/lib/draco/" };
const data = await loader.loadAsync("/scenes/model.glb");
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every required extension plugin is registered before loading
const registered = new Set(loader._extensions?.map(e => e.name) ?? []); // or track registrations yourself
for (const name of gltf.extensionsRequired ?? []) {
  if (!registered.has(name)) console.warn(`Register plugin for ${name} before loading`);
}

Type guard

function allRequiredExtensionsRegistered(registeredNames, gltf) {
  const required = gltf.extensionsRequired ?? [];
  return required.every(name => registeredNames.includes(name));
}

Try / catch

try {
  await loader.loadAsync(url);
} catch (e) {
  if (/is not available$/.test(e.message)) {
    const ext = e.message.match(/Required extension (\S+) is not available/)?.[1];
    console.error(`Add support for ${ext} (decoder/plugin) or re-export without it`);
  } else throw e;
}

Prevention

When it happens

Trigger: Loading a .glb/.gltf that requires e.g. KHR_draco_mesh_compression, KHR_texture_basisu, or EXT_meshopt_compression without registering the corresponding Babylon extension plugin.

Common situations: Exporting from Blender/DCC with Draco or meshopt compression but not wiring the decoder or extension plugin in the app; forgetting to import the extension package (tree-shaking removed it); using a viewer subset of the library that excludes optional loaders.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/687ed0adffdfd6cf. Report an issue: GitHub.