{"record":{"id":"3780686cde33acb2","repo":"dotnet/runtime","slug":"using-node-without-crypto-support-to-enable-curre","errorCode":null,"errorMessage":"Using node without crypto support. To enable current operation, either provide polyfill for 'globalThis.crypto.getRandomValues' or enable 'node:crypto' module.","messagePattern":"Using node without crypto support\\. To enable current operation, either provide polyfill for 'globalThis\\.crypto\\.getRandomValues' or enable 'node:crypto' module\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/native/libs/Common/JavaScript/loader/polyfills.ts","lineNumber":53,"sourceCode":"        }\n    }\n    if (ENVIRONMENT_IS_NODE) {\n        if (!globalThis.crypto) {\n            globalThis.crypto = <any>{};\n        }\n        if (!globalThis.crypto.getRandomValues) {\n            let nodeCrypto: any = undefined;\n            try {\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore:\n                nodeCrypto = await import(/*! webpackIgnore: true */\"node:crypto\");\n            } catch (err: any) {\n                // Noop, error throwing polyfill provided bellow\n            }\n\n            if (!nodeCrypto) {\n                globalThis.crypto.getRandomValues = () => {\n                    throw new Error(\"Using node without crypto support. To enable current operation, either provide polyfill for 'globalThis.crypto.getRandomValues' or enable 'node:crypto' module.\");\n                };\n            } else if (nodeCrypto.webcrypto) {\n                globalThis.crypto = nodeCrypto.webcrypto;\n            } else if (nodeCrypto.randomBytes) {\n                const getRandomValues = (buffer: Uint8Array) => {\n                    if (buffer) {\n                        buffer.set(nodeCrypto.randomBytes(buffer.length));\n                    }\n                };\n                globalThis.crypto.getRandomValues = getRandomValues as any;\n            }\n        }\n        if (!globalThis.performance) {\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore:\n            globalThis.performance = (await import(/*! webpackIgnore: true */\"perf_hooks\")).performance;\n        }\n    }","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/native/libs/Common/JavaScript/loader/polyfills.ts#L35-L71","documentation":"initPolyfillsEarly() in Node detects that globalThis.crypto.getRandomValues is missing and that dynamic import('node:crypto') failed. It then installs a getRandomValues stub that throws this exact message when called. So the error fires later, at the first crypto use, not at polyfill install time. Node 18+ has webcrypto built-in; older or stripped Node builds may not.","triggerScenarios":"Running under Node.js where node:crypto is unavailable (custom Node build with crypto disabled, a bundler that stubbed out node:crypto, a sandboxed runtime), and the .NET runtime then invokes crypto.getRandomValues for GUID/random generation.","commonSituations":"Bundling the loader with webpack/rollup without marking node:crypto as external; running in a restricted sandbox (e.g. some serverless runtimes); very old Node (<15) without webcrypto; an environment that deleted globalThis.crypto before startup.","solutions":["Ensure node:crypto is resolvable: configure bundlers with { externals: ['node:crypto'] } or target:'node'.","Upgrade to Node 18+ where globalThis.crypto.webcrypto is available natively.","Provide a polyfill before bootstrapping: globalThis.crypto.getRandomValues = require('crypto').randomFillSync, or use the 'crypto' package's webcrypto.","If you cannot enable node:crypto, install a custom getRandomValues backed by any secure RNG available in your host."],"exampleFix":"// before\nconst dotnet = await dotnet.create(); // throws inside runtime when crypto used\n\n// after — polyfill before create\nconst { webcrypto } = require('node:crypto');\nglobalThis.crypto = webcrypto;\nconst dotnet = await dotnet.create();","handlingStrategy":"fallback","validationCode":"if (typeof globalThis.crypto?.getRandomValues !== 'function') {\n  try { await import('node:crypto'); }\n  catch { throw new Error('node:crypto unavailable — polyfill globalThis.crypto.getRandomValues before boot'); }\n}","typeGuard":"function hasSecureRandom(g: any): g is { crypto: { getRandomValues: (b: Uint8Array) => Uint8Array } } {\n  return typeof g?.crypto?.getRandomValues === 'function';\n}","tryCatchPattern":null,"preventionTips":["Run on Node 18+ where webcrypto is global.","Mark node:crypto external in bundler configs.","Assert globalThis.crypto.getRandomValues in a bootstrap self-test."],"tags":["node","crypto","polyfill","environment","runtime"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}