BabylonJS/Babylon.js · error

No plugin or fallback for ${pluginExtension ?? fileInfo.url}

Error message

No plugin or fallback for ${pluginExtension ?? fileInfo.url}

What it means

SceneLoader resolved the requested file extension (or the URL) but found no registered loader plugin for it, and no default fallback plugin is registered either. SceneLoader only supports formats whose plugins (e.g. .glb, .obj, .stl) have been registered/imported into the scene.

Source

Thrown at packages/dev/core/src/Loading/sceneLoader.ts:704

          : getPluginForExtension(fileExtension, false);

    if (!registeredPlugin && fileExtension) {
        if (fileInfo.url && !fileInfo.url.startsWith("blob:")) {
            // Fetching head content to get the mime type
            const response = await _FetchAsync(fileInfo.url, { method: "HEAD", responseHeaders: ["Content-Type"] });
            const mimeType = response.headerValues ? response.headerValues["Content-Type"] : "";
            if (mimeType) {
                registeredPlugin = getPluginForMimeType(mimeType);
            }
        }

        if (!registeredPlugin) {
            registeredPlugin = getDefaultPlugin();
        }
    }

    if (!registeredPlugin) {
        throw new Error(`No plugin or fallback for ${pluginExtension ?? fileInfo.url}`);
    }

    if (pluginOptions?.[registeredPlugin.plugin.name]?.enabled === false) {
        throw new Error(`The '${registeredPlugin.plugin.name}' plugin is disabled via the loader options passed to the loading operation.`);
    }

    if (fileInfo.rawData && !registeredPlugin.isBinary) {
        throw new Error("Loading from ArrayBufferView can not be used with plugins that don't support binary loading.");
    }

    // For plugin factories, the plugin is instantiated on each SceneLoader operation. This makes options handling
    // much simpler as we can just pass the options to the factory, rather than passing options through to every possible
    // plugin call. Given this, options are only supported for plugins that provide a factory function.
    let plugin: SceneLoaderPlugin;
    if (IsFactory(registeredPlugin.plugin)) {
        const pluginFactory = registeredPlugin.plugin;
        try {
            // Only await when the factory is actually asynchronous, so that for synchronous factories the plugin is

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Import the loader plugin for the format before loading, e.g. import "@babylonjs/loaders/glTF".
  2. Verify the file extension / pluginExtension string matches a supported format (gltf, glb, obj, stl, dae...).
  3. Register the plugin manually via SceneLoader.RegisterPlugin if using a custom loader.

Example fix

// before
import { SceneLoader } from "@babylonjs/core";
await SceneLoader.ImportMeshAsync("", url, "model.glb", scene); // no plugin registered

// after
import "@babylonjs/loaders/glTF";
await SceneLoader.ImportMeshAsync("", url, "model.glb", scene);
Defensive patterns

Strategy: fallback

Validate before calling

const supported = [".gltf", ".glb", ".obj", ".stl", ".dae", ".splat"];
const ext = url.slice(url.lastIndexOf("."));
if (!supported.includes(ext)) console.warn("No known Babylon.js loader for", ext);

Try / catch

try {
  await BABYLON.SceneLoader.ImportMeshAsync("", root, file, scene);
} catch (e) {
  if ((e as Error).message.startsWith("No plugin or fallback")) {
    console.error("Loader plugin missing for", file, "— import @babylonjs/loaders/* side-effect module");
  }
}

Prevention

When it happens

Trigger: Loading a file whose extension has no registered plugin (e.g. ".usdz", ".fbx") or calling with a pluginExtension that was never registered, when no default plugin fallback exists.

Common situations: Forgetting to import the side-effect module (e.g. @babylonjs/loaders/glTF) in ES6/webpack builds; typos in the extension; loading a format Babylon.js does not support at all.

Related errors


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