dotnet/aspnetcore · critical · Error
Failed to start platform. Reason: ${ex}
Error message
Failed to start platform. Reason: ${ex} What it means
Thrown by startCore when either the Mono WebAssembly platform failed to load (loadWebAssemblyPlatformIfNotStarted) or platform.start() rejected. The original exception is wrapped and re-thrown so the underlying cause (download failure, runtime panic, out-of-memory, incompatible browser) is preserved in the message.
Source
Thrown at src/Components/Web.JS/src/Boot.WebAssembly.Common.ts:187
};
Blazor._internal.endUpdateRootComponents = (batchId: number) =>
components.onAfterUpdateRootComponents?.(batchId);
Blazor._internal.attachRootComponentToElement = (selector, componentId, rendererId) => {
const element = componentAttacher.resolveRegisteredElement(selector);
if (!element) {
attachRootComponentToElement(selector, componentId, rendererId);
} else {
attachRootComponentToLogicalElement(rendererId, element, componentId, false);
}
};
try {
await platformLoadPromise;
await platform.start();
} catch (ex) {
throw new Error(`Failed to start platform. Reason: ${ex}`);
}
// Start up the application
platform.callEntryPoint();
// At this point .NET has been initialized (and has yielded), we can't await the promise because it will
// only end when the app finishes running
const initializer = getInitializer();
initializer.invokeAfterStartedCallbacks(Blazor);
started = true;
resolve();
}
export function hasStartedWebAssembly(): boolean {
return startPromise !== undefined;
}
export function waitForBootConfigLoaded(): Promise<MonoConfig> {
return bootConfigPromise;View on GitHub (pinned to 294cab2f9b)
Solutions
- Read the wrapped ${ex} in the message to identify the root cause (network status, CSP, runtime error) and address that first.
- Verify _framework/blazor.boot.json and all referenced .dll/.wasm files are deployed and reachable (check Network tab for 404/failure).
- Loosen Content-Security-Policy to allow 'wasm-unsafe-eval' (and the script/wasm sources) for the app origin.
- Clear browser cache / service-worker cache to remove stale build artifacts after a redeploy.
- If AOT/trimming is enabled, disable it or add the necessary trim-safe roots to confirm the runtime initializes.
Example fix
// before: unhandled rejection aborts the page
Blazor.start().catch(e => console.error(e));
// message: "Failed to start platform. Reason: TypeError: Failed to fetch dynamically imported module ...wasm"
// after: surface the underlying cause and retry once
try {
await Blazor.start();
} catch (e) {
console.error('Platform start failed:', e.message);
const cause = e.message.replace('Failed to start platform. Reason: ', '');
// inspect `cause`, then e.g. reload after cache-bust
if (/Failed to fetch/.test(cause)) location.reload();
} Defensive patterns
Strategy: try-catch
Validate before calling
// Most root causes (network, runtime) can't be pre-validated cheaply.
// Best-effort pre-flight: probe the boot config and CSP.
async function preflightWasm() {
const r = await fetch('_framework/blazor.boot.json', { cache: 'no-cache' });
if (!r.ok) throw new Error('blazor.boot.json unreachable: ' + r.status);
// CSP must allow wasm-unsafe-eval; surface a hint if missing.
const csp = document.querySelector('meta[http-equiv="Content-Security-Policy"]')?.getAttribute('content') || '';
if (csp && !/wasm-unsafe-eval/.test(csp)) {
console.warn('CSP may block WebAssembly: add \'wasm-unsafe-eval\'.');
}
} Type guard
// Runtime support check before booting.
function browserSupportsWasm(): boolean {
return typeof WebAssembly === 'object' && typeof WebAssembly.instantiate === 'function';
} Try / catch
try {
await Blazor.start();
} catch (e) {
const msg = (e as Error).message;
if (msg.startsWith('Failed to start platform.')) {
const cause = msg.replace('Failed to start platform. Reason: ', '');
console.error('WASM platform failed:', cause);
if (/Failed to fetch|NetworkError|404/.test(cause)) {
// bust stale cache and retry once
if ('caches' in window) await caches.delete('blazor');
location.reload();
}
} else throw e;
} Prevention
- Always await Blazor.start() inside try/catch and surface the wrapped cause.
- Ensure _framework/ artifacts are deployed and reachable (watch for 404s).
- Allow 'wasm-unsafe-eval' (and your script/wasm sources) in CSP.
- Cache-bust after redeploy to avoid stale .dll/.wasm mismatch.
- Smoke-test on the lowest-spec target browser you support.
When it happens
Trigger: Network failure downloading _framework/blazor.boot.json, the .wasm binary, or the .dll files; the Mono runtime throwing during initialization; a browser without WebAssembly support or with a Content-Security-Policy that blocks wasm-unsafe-eval; out-of-memory on low-end devices; AOT mismatch between published artifacts.
Common situations: Offline or flaky network during app load; aggressive CSP without 'wasm-unsafe-eval'; publishing with trimming/AOT that removes required types; cached stale build artifacts after redeploy; older mobile browsers without full WASM support.
Related errors
- WebAssembly options have already been configured.
- Blazor WebAssembly has already started.
- Blazor WebAssembly has not started.
- Blazor WebAssembly has not initialized.
- Blazor has already started.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/23cc510be07517cb.
Report an issue: GitHub.