BabylonJS/Babylon.js · error · Error

Failed to fetch image "${url}": ${response.status} ${respons

Error message

Failed to fetch image "${url}": ${response.status} ${response.statusText}

What it means

LoadImageToTexture2DArrayLayerAsync fetches an image URL and throws a descriptive Error when the HTTP response is not ok (status outside 200-299), including the status code and status text in the message.

Source

Thrown at packages/dev/core/src/Materials/Textures/rawTexture2DArray.functions.ts:96

}

/**
 * Fetches an image from a url, decodes it and uploads it into a single layer of a 2D array texture.
 * @param texture defines the 2D array texture to upload into
 * @param url defines the url of the image to load
 * @param layer defines the array layer to upload into
 * @param options defines optional upload settings (invertY, premultiplyAlpha)
 * @returns a promise resolved once the layer has been uploaded
 */
export async function LoadImageToTexture2DArrayLayerAsync(
    texture: RawTexture2DArray,
    url: string,
    layer: number,
    options?: IUploadImageToTexture2DArrayLayerOptions
): Promise<void> {
    const response = await fetch(url);
    if (!response.ok) {
        throw new Error(`Failed to fetch image "${url}": ${response.status} ${response.statusText}`);
    }
    const blob = await response.blob();
    const bitmap = await createImageBitmap(blob);
    try {
        UploadImageToTexture2DArrayLayer(texture, bitmap, layer, options);
    } finally {
        bitmap.close();
    }
}

/**
 * Options controlling the creation of a 2D array texture from a KTX2 file.
 */
export interface ICreateTexture2DArrayFromKTX2Options {
    /** Defines if mip levels should be generated (true by default) */
    generateMipMaps?: boolean;
    /** Defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default) */
    samplingMode?: number;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Verify the URL resolves in the browser/curl and returns 200
  2. Add authentication headers via a pre-fetched blob or proxy if the asset is protected
  3. Check dev-server/CDN config serves the image (public path, base URL)
  4. Handle 404 by checking the asset build includes the image

Example fix

// before
await LoadImageToTexture2DArrayLayerAsync(tex, `/textures/${name}.png`, i);
// after
const url = new URL(`/textures/${name}.png`, import.meta.env.ASSET_BASE).href;
const res = await fetch(url);
if (!res.ok) throw new Error(`Missing asset ${url}: ${res.status}`);
await LoadImageToTexture2DArrayLayerAsync(tex, url, i);
Defensive patterns

Strategy: retry

Validate before calling

async function assertFetchable(url: string): Promise<Response> {
  const res = await fetch(url, { method: "HEAD" });
  if (!res.ok) throw new Error(`Image ${url} not available: ${res.status}`);
  return res;
}

Try / catch

try {
  await LoadImageToTexture2DArrayLayerAsync(tex, url, layer);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Failed to fetch image")) {
    if (isTransient(e)) await retry(() => LoadImageToTexture2DArrayLayerAsync(tex, url, layer), 3);
    else usePlaceholderLayer(layer);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling LoadImageToTexture2DArrayLayerAsync with a URL that 404s, 401/403s, or 5xx — wrong path, missing auth headers (fetch here sends no credentials), CORS-blocked or server-down responses.

Common situations: Typos in asset paths, images behind authentication, dev server without the asset folder, or CDN misconfiguration.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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