Error message
SyntaxError: Cannot create a key using the specified key usages.
Also printed as
- SyntaxError: Usages cannot be empty when creating a key.
- SyntaxError: An invalid or illegal string was specified
- SyntaxError: A required parameter was missing or out-of-range
Chromium: "Cannot create a key using the specified key usages." or "Usages cannot be empty when creating a key."; Firefox: "An invalid or illegal string was specified"; Safari/WebKit: "A required parameter was missing or out-of-range". Match on `e.name === "SyntaxError"`.
WebCrypto SubtleCrypto.importKey / generateKey — DOMException SyntaxError (Chromium / Firefox / WebKit)
What it means
The `keyUsages` array does not fit the key being created. WebCrypto defines which usages each key type may have: an ECDSA or RSA public key may only `verify`, a private key only `sign`; ECDH public keys take no usages; and creating a private or secret key with an empty usage list is not allowed. The browser rejects the call with a `SyntaxError` DOMException before the key exists. This is different from `InvalidAccessError`, which you get later when an existing key is used for an operation it was not created for.
Why it happens
A public key imported with sign (or a private key with verify)
commonCopying the same `["sign", "verify"]` array into every `importKey` call fails for single keys: only `generateKey` splits the list between the two halves of a pair.
An empty usage list
common`generateKey(alg, true, [])` or importing a private key with `[]`. Keys must be created for at least one purpose.
ECDH and ECDSA mixed up
occasionalAn ECDH key imported with `["sign"]` or an ECDSA key with `["deriveBits"]` fails: the same curve point is a different key type for each algorithm.
How to fix it
- 1.
Give each key the usages of its role
Public keys: `verify` (signatures) or `[]` (ECDH peer keys); private keys: `sign` or `deriveBits`/`deriveKey`. Keep usages minimal — they are part of WebCrypto's least-privilege model.
js const alg = { name: "ECDSA", namedCurve: "P-256" }; // Public keys verify, private keys sign: const publicKey = await crypto.subtle.importKey("spki", spkiDer, alg, false, ["verify"]); const privateKey = await crypto.subtle.importKey("pkcs8", pkcs8Der, alg, false, ["sign"]); // ECDH keys derive; their public half takes no usages at all: const peer = await crypto.subtle.importKey("raw", point, { name: "ECDH", namedCurve: "P-256" }, false, []);
Related errors
InvalidAccessError: Unable to use this key to verifyWebCrypto crypto.subtle.sign / verifyDataError: Data provided to an operation does not meet requirementsWebCrypto crypto.subtle.importKeyInvalidAccessError: Failed to execute 'exportKey' on 'SubtleCrypto': key is not…WebCrypto SubtleCrypto.exportKey / wrapKey