Error message
TypeError: Cannot read properties of undefined (reading 'digest')
Also printed as
- TypeError: Cannot read properties of undefined (reading 'importKey')
- TypeError: can't access property "digest", crypto.subtle is undefined
- TypeError: undefined is not an object (evaluating 'crypto.subtle.digest')
The wording is the engine's generic TypeError: Chromium/V8 "Cannot read properties of undefined (reading 'digest')", Firefox "can't access property \"digest\", crypto.subtle is undefined", Safari/WebKit "undefined is not an object (evaluating 'crypto.subtle.digest')". The method name follows the first call (`importKey`, `sign`, `generateKey`…).
WebCrypto — window.crypto.subtle is undefined outside a secure context (Chromium / Firefox / WebKit)
What it means
`crypto.subtle` does not exist on this page, so the first call on it fails with a generic "undefined" TypeError. Browsers expose `SubtleCrypto` only in secure contexts: pages served over HTTPS, from `http://localhost` / `127.0.0.1`, or from `file:` URLs. The same code works on your machine at localhost and breaks as soon as the page is opened over plain HTTP from another host name or IP address. `crypto.getRandomValues` keeps working, which makes the failure look selective.
Why it happens
The page is served over plain HTTP
commonStaging hosts, intranet tools and preview environments without TLS are not secure contexts. Every WebCrypto feature disappears there, by specification.
A dev server opened via a LAN address
common`http://localhost:5173` is secure, `http://192.168.1.20:5173` (testing on a phone) is not. Code that worked during development fails on the device.
An insecure frame or WebView
occasionalA secure page embedded in an `http:` parent frame, or a WebView loading local content over a custom insecure scheme, is not a secure context either.
How to fix it
- 1.
Detect it and fail with a clear message
Check `window.isSecureContext` before using WebCrypto. Do not fall back to a JavaScript crypto polyfill silently — the page's integrity is not guaranteed without TLS anyway.
js if (!window.isSecureContext || !globalThis.crypto?.subtle) { throw new Error("WebCrypto needs HTTPS (or http://localhost). Current origin: " + location.origin); } const digest = await crypto.subtle.digest("SHA-256", data); - 2.
Serve the page over HTTPS
Use TLS for every environment, including development servers you open from other devices; tools like mkcert create locally trusted certificates.
bash # Local HTTPS for a dev server reachable from other devices mkcert -install mkcert dev.example.test 192.168.1.20 localhost # Vite: server.https = { key: fs.readFileSync("dev.example.test+2-key.pem"), cert: fs.readFileSync("dev.example.test+2.pem") }
Related errors
DataError: Data provided to an operation does not meet requirementsWebCrypto crypto.subtle.importKeyTypeError: Failed to execute 'importKey' on 'SubtleCrypto': The provided value…WebCrypto SubtleCrypto.importKeySecurityError: The relying party ID is not a registrable domain suffix of, nor…WebAuthn navigator.credentials.create() / get()