{"record":{"id":"c557f7dd6ec3d060","repo":"denoland/deno","slug":"can-not-create-secret-key-from-type-key","errorCode":null,"errorMessage":"can not create secret key from ${type} key","messagePattern":"can not create secret key from (.+?) key","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/keys.ts","lineNumber":1087,"sourceCode":"  key: string | ArrayBufferView | ArrayBuffer | KeyObject | CryptoKey,\n  encoding?: string,\n): KeyObject {\n  if (isCryptoKey(key)) {\n    if (key.type !== \"secret\") {\n      throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(key.type, \"secret\");\n    }\n    return KeyObject.from(key);\n  }\n  const preparedKey = prepareSecretKey(key, encoding, true);\n  if (isArrayBufferView(preparedKey) || isAnyArrayBuffer(preparedKey)) {\n    const handle = op_node_create_secret_key(preparedKey);\n    return new SecretKeyObject(handle);\n  } else {\n    const type = op_node_key_type(preparedKey);\n    if (type === \"secret\") {\n      return new SecretKeyObject(preparedKey);\n    } else {\n      throw new TypeError(`can not create secret key from ${type} key`);\n    }\n  }\n}\n\n// Deserializer for KeyObjects transferred via structured clone. Registered\n// eagerly (so workers can resurrect a KeyObject before this module loads) from\n// `02_register_cloneable.js`; the impl stays lazy here.\nfunction deserializeNodeCryptoKeyObject(data) {\n  switch (data.keyType) {\n    case \"secret\": {\n      const handle = op_node_create_secret_key(data.keyData);\n      return new SecretKeyObject(handle);\n    }\n    case \"public\": {\n      const handle = op_node_create_public_key(\n        data.keyData,\n        \"der\",\n        \"spki\",","sourceCodeStart":1069,"sourceCodeEnd":1105,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/keys.ts#L1069-L1105","documentation":"createSecretKey() throws TypeError 'can not create secret key from <type> key' when the input resolves to a node:crypto KeyObject whose type is 'public' or 'private'. After prepareSecretKey normalizes the input, the polyfill asks the handle for its key type via an internal op and refuses asymmetric material — only buffers, array buffers, and secret KeyObjects are accepted.","triggerScenarios":"const { privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048 }); createSecretKey(privateKey) — the KeyObject type is 'private', so the message reads 'can not create secret key from private key'.","commonSituations":"Destructured key pairs passed into a helper that expects a shared secret; migration from code that stored everything as Buffers; copying createSecretKey(buffer) patterns with a KeyObject variable swapped in.","solutions":["Use the key as its own type: public/private KeyObjects already are KeyObjects — return them directly, or use createPublicKey/createPrivateKey for CryptoKeys","Guard with keyObject.type === 'secret' before calling createSecretKey","For derived shared secrets (e.g., ECDH), pass the derived secret buffer (diffieHellman() output), not a key object"],"exampleFix":"// before\nconst ko = createSecretKey(privateKey); // TypeError: can not create secret key from private key\n\n// after\nif (input.type === 'secret') {\n  ko = createSecretKey(input);\n} else {\n  ko = input; // already a public/private KeyObject\n}","handlingStrategy":"type-guard","validationCode":"if (isKeyObject(input)) {\n  if (input.type !== 'secret') {\n    throw new TypeError(`expected a secret KeyObject, got ${input.type}`);\n  }\n  return input; // already a secret KeyObject\n}\nreturn createSecretKey(input);","typeGuard":"function isSecretKeyObject(k: unknown): k is KeyObject & { type: 'secret' } {\n  return isKeyObject(k) && (k as KeyObject).type === 'secret';\n}","tryCatchPattern":"try {\n  ko = createSecretKey(input);\n} catch (e) {\n  if (e instanceof TypeError && /can not create secret key from/.test(e.message)) {\n    // input was an asymmetric KeyObject: pass it through instead\n    ko = input as KeyObject;\n  } else throw e;\n}","preventionTips":["KeyObjects of public/private type are already usable — never wrap them in createSecretKey","Pass derived shared secrets as Buffers (e.g., diffieHellman() output)","Validate input kinds at API boundaries: Buffer vs KeyObject vs CryptoKey"],"tags":["crypto","keyobject","node-compat","type-mismatch"],"backgroundTag":"wrong-key-object-type","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}