dotnet/runtime · critical · Error
Mismatched git hashes between loader and runtime. Loader
Error message
Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, DOTNET: ${_ems_.DOTNET.gitHash} What it means
The Native module (System.Native.Browser/native) verifies during dotnetInitializeModule() that the loader-supplied runtimeBuildInfo.gitHash matches _ems_.DOTNET.gitHash (the hash baked into the core runtime bundle). A mismatch means the native-browser support JS was built from a different commit than the core .NET runtime.
Solutions
- Publish/copy the entire _framework (or equivalent) folder from one consistent build so all dotnet JS bundles share a git hash.
- Clear browser/CDN/proxy caches that may serve a mix of old and new JS.
- Rebuild from clean (rm -rf bin obj) to guarantee the workload stamps a single hash across all support modules.
- Verify the deployed dotnet.runtime.js, the native support JS, and the WASM all carry the same version metadata.
Example fix
// before: dotnet.runtime.js from SDK 8.0.x, System.Native support JS from 9.0.x // after: single consistent workload publish // dotnet workload restore // dotnet publish -c Release (copy whole _framework output)
Defensive patterns
Strategy: validation
Validate before calling
// Verify all support modules share the runtime's git hash before initializing.
function assertConsistentBuild(runtimeApi: any, nativeHash: string) {
const loader = runtimeApi?.runtimeBuildInfo?.gitHash;
if (loader && loader !== nativeHash) {
throw new Error(`Build mismatch: loader=${loader} native=${nativeHash}. Redeploy consistently.`);
}
} Type guard
null
Try / catch
null
Prevention
- Deploy the full _framework from one publish; never mix SDK versions.
- Cache-bust and fingerprint JS bundles to prevent stale-asset mixing.
- Clean (rm -rf bin obj) before building to guarantee a single stamped hash.
- Verify the hash reported by each module post-deploy.
When it happens
Trigger: dotnet.runtime.js (DOTNET bundle) and the System.Native native-support JS come from different builds; _ems_.DOTNET.gitHash is populated but differs from the loader-reported hash.
Common situations: Stale cached dotnet.*.js while the .wasm/runtime JS is refreshed; hand-assembled wwwroot mixing files from SDK versions; partial publish; dev workflow that rebuilds only one project.
Related errors
- Mismatched git hashes between loader and runtime. Loader
- Mismatched git hashes between loader and runtime. Loader
- Mismatched git hashes between loader and runtime. Loader
- Failed to initialize ICU data
- Failed to load ICU data
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/53a4f0abbfd8301b.
Report an issue: GitHub.
Appendix: source
Thrown at src/native/libs/System.Native.Browser/native/index.ts:25
import { _ems_ } from "../../Common/JavaScript/ems-ambient";
import GitHash from "consts:gitHash";
export { SystemJS_RandomBytes } from "./crypto";
export { SystemJS_GetLocaleInfo } from "./globalization-locale";
export { SystemJS_RejectMainPromise, SystemJS_ResolveMainPromise, SystemJS_MarkAsyncMain, SystemJS_ConsoleClear } from "./main";
export { SystemJS_ScheduleTimer, SystemJS_ScheduleBackgroundJob, SystemJS_ScheduleFinalization, SystemJS_ScheduleDiagnosticServer } from "./scheduling";
export { ds_rt_websocket_close, ds_rt_websocket_create, ds_rt_websocket_poll, ds_rt_websocket_recv, ds_rt_websocket_send, ds_rt_browser_performance_measure } from "./diagnostics";
export const gitHash = GitHash;
export function dotnetInitializeModule(internals: InternalExchange): void {
if (!Array.isArray(internals)) throw new Error("Expected internals to be an array");
const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI];
if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI");
if (runtimeApi.runtimeBuildInfo.gitHash && runtimeApi.runtimeBuildInfo.gitHash !== _ems_.DOTNET.gitHash) {
throw new Error(`Mismatched git hashes between loader and runtime. Loader: ${runtimeApi.runtimeBuildInfo.gitHash}, DOTNET: ${_ems_.DOTNET.gitHash}`);
}
internals[InternalExchangeIndex.NativeBrowserExportsTable] = nativeBrowserExportsToTable({
getWasmMemory,
getWasmTable,
SystemJS_ScheduleDiagnosticServer: _ems_._SystemJS_ScheduleDiagnosticServer,
SystemJS_GetMethodName: (pMethodDesc: number) => _ems_._SystemJS_GetMethodName(pMethodDesc),
});
_ems_.dotnetUpdateInternals(internals, _ems_.dotnetUpdateInternalsSubscriber);
setupEmscripten();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function nativeBrowserExportsToTable(map: NativeBrowserExports): NativeBrowserExportsTable {
// keep in sync with nativeBrowserExportsFromTable()
return [
map.getWasmMemory,
map.getWasmTable,View on GitHub (pinned to 60108ba66e)