dotnet/runtime · critical · Error

Unsupported Webcil version

Error message

Unsupported Webcil version: ${webcilVersion}

What it means

Thrown by the Webcil host inside the corerun WebAssembly glue (libCorerun.js) after it instantiates the Webcil wasm image. The host only accepts the webcil protocol versions 0 and 1; any other value reported by the wasm export `webcilVersion` is treated as an incompatible runtime/host pairing and aborts loading the image. The check exists so a newer (or older) runtime binary cannot be silently driven by an incompatible host, which would corrupt the runtime payload.

Solutions

  1. Rebuild both the Webcil assemblies and the corerun wasm host from the same source tree / SDK so the protocol version agrees.
  2. Clean previous build outputs (bin/obj) and any cached wasm artifacts, then `dotnet publish` the project again.
  3. Confirm the runtime package version reported by the loaded `dotnet.native.wasm` matches the SDK used to compile the Webcil images.
  4. If you intentionally changed the webcil protocol, update the upper bound in libCorerun.js:266 to support the new version.

Example fix

// before: mismatched artifacts after partial upgrade
//  -> runtime throws `Unsupported Webcil version: 2`

// after: rebuild from one source tree so host + payload agree
dotnet clean && dotnet build -c Release
// republish the wasm app to regenerate dotnet.native.wasm + webcil payloads
dotnet publish -c Release -o ./publish
Defensive patterns

Strategy: validation

Validate before calling

// Verify the webcil protocol version before instantiating
function isSupportedWebcilVersion (wasmInstance) {
  const v = wasmInstance?.exports?.webcilVersion?.value;
  return typeof v === 'number' && v >= 0 && v <= 1;
}
// if (!isSupportedWebcilVersion(wasmInstance)) { /* abort with a clear message, rebuild */ }

Type guard

function isWebcilInstanceCompatible (inst: WebAssembly.Instance): boolean {
  const v = (inst.exports as any).webcilVersion;
  return v != null && typeof v.value === 'number' && v.value >= 0 && v.value <= 1;
}

Prevention

When it happens

Trigger: Reached only after a Webcil WebAssembly instance is successfully constructed for a Webcil image. The branch `webcilVersion > 1 || webcilVersion < 0` at src/coreclr/hosts/corerun/wasm/libCorerun.js:266-267 fires when `wasmInstance.exports.webcilVersion.value` is outside [0,1]. This happens when the Webcil payload (.dll/.webcil) is produced by a future or dev toolchain whose protocol version diverged from the corerun wasm host that emcc linked into the binary.

Common situations: Mixing a .NET runtime build from one branch with a corerun wasm host from another; upgrading the .NET SDK / runtime to a preview that bumped the webcil protocol without rebuilding the native corerun host; using a stale `dotnet.native.wasm` artifact alongside freshly built Webcil assemblies; man-in-the-middle/partial deploy that ships half of a runtime update.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/de2331760eb05b4e. Report an issue: GitHub.

Appendix: source

Thrown at src/coreclr/hosts/corerun/wasm/libCorerun.js:267

                        rtlRestoreContextTag: wasmExports.__coreclr_wasm_rtlrestorecontext_tag,
                        table: wasmTable,
                        tableBase: new WebAssembly.Global({ value: "i32", mutable: false }, tableStartIndex),
                        imageBase: new WebAssembly.Global({ value: "i32", mutable: false }, payloadPtr),
                        // Runtime-async continuation return value, shared with the runtime module.
                        asyncContinuation: wasmExports.__async_continuation
                    }
                });
            } catch (e) {
                const errorMessage = e instanceof Error ? e.message : String(e);
                console.error("Failed to construct WebAssembly instance for Webcil image:", { wasmPath, errorMessage });
                return false;
            } finally {
                stackRestore(sp);
            }

            const webcilVersion = wasmInstance.exports.webcilVersion.value;
            if ((webcilVersion > 1) || (webcilVersion < 0)) {
                throw new Error(`Unsupported Webcil version: ${webcilVersion}`);
            }

            wasmInstance.exports.getWebcilPayload(payloadPtr, payloadSize);
            if (tableSize > 0) {
                wasmInstance.exports.fillWebcilTable();
            }
            HEAPU32[outDataStartPtr >>> 2 >>> 0] = payloadPtr;
            HEAPU32[outSize >>> 2 >>> 0] = payloadSize;
            HEAPU32[(outSize + 4) >>> 2 >>> 0] = 0;
            return true;
        }
    };
    const patchNODERAWFS = {
        cwd: () => {
            // drop windows drive letter for NODEFS cwd to pretend we are in unix
            const path = process.cwd();
            return NODEFS.isWindows
                ? path.replace(/^[a-zA-Z]:/, "").replace(/\\/g, "/")

View on GitHub (pinned to 60108ba66e)