denoland/deno · error · TypeError
Only 'sha512' is supported for Ed25519 keys
Error message
Only 'sha512' is supported for Ed25519 keys
What it means
Ed25519 signs the raw message with SHA-512 built into the algorithm, so there is no selectable digest. One-shot crypto.sign() only accepts algorithm === null/undefined or the literal "sha512" when the key type is ed25519; any other digest string throws this TypeError.
Source
Thrown at ext/node/polyfills/internal/crypto/sig.ts:411
try {
const res = prepareAsymmetricKey(key, kConsumePrivate);
let handle;
if (ReflectHas(res, "handle")) {
handle = res.handle;
} else {
handle = op_node_create_private_key(
res.data,
res.format,
res.type ?? "",
res.passphrase,
);
}
let result: Buffer;
const keyType = op_node_get_asymmetric_key_type(handle);
if (keyType === "ed25519") {
if (algorithm != null && algorithm !== "sha512") {
throw new TypeError("Only 'sha512' is supported for Ed25519 keys");
}
result = new FastBuffer(64);
op_node_sign_ed25519(handle, dataBytes, result);
} else if (keyType === "ed448") {
const keyOpts = typeof key === "object" && key !== null &&
!(ObjectPrototypeIsPrototypeOf(KeyObject.prototype, key))
? key as Record<string, unknown>
: null;
const ctx = keyOpts?.context;
if (
ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, ctx) &&
ctx.length > 0
) {
throw new TypeError("Context parameter is unsupported");
}
result = new FastBuffer(114);
op_node_sign_ed448(handle, dataBytes, result);
} else {View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Pass null as the algorithm for ed25519 keys: crypto.sign(null, data, ed25519Key).
- Branch on key.asymmetricKeyType: use null for "ed25519"/"ed448", the digest otherwise.
- In JWT code, map EdDSA/OKP keys to digestless signing instead of RS/ES hashing.
Example fix
// before
const sig = crypto.sign("sha256", data, key); // throws when key is ed25519
// after
const alg = key.asymmetricKeyType === "ed25519" ? null : "sha256";
const sig = crypto.sign(alg, data, key); Defensive patterns
Strategy: validation
Validate before calling
function digestArgFor(key, requested) {
const type = key.asymmetricKeyType ?? key.key?.asymmetricKeyType;
if (type === "ed25519" || type === "ed448") return null;
if (requested != null) return requested;
throw new TypeError("digest required for this key type");
}
const sig = crypto.sign(digestArgFor(key, "sha256"), data, key); Type guard
const isDigestlessKey = (key) => {
const t = key.asymmetricKeyType ?? key.key?.asymmetricKeyType;
return t === "ed25519" || t === "ed448";
}; Try / catch
try {
sig = crypto.sign(alg, data, key);
} catch (e) {
if (e instanceof TypeError && /Only 'sha512' is supported for Ed25519/.test(e.message)) {
throw new Error("pass null as the algorithm for ed25519 keys (SHA-512 is built in)");
}
throw e;
} Prevention
- Never hardcode a digest in shared signing helpers — derive it from key.asymmetricKeyType.
- For JWTs, map alg headers: EdDSA -> null, RS256 -> sha256, ES384 -> sha384.
- Only null or the literal "sha512" are valid for ed25519.
When it happens
Trigger: crypto.sign("sha256", message, ed25519KeyObject); a generic signWith(algorithm, ...) helper with a hardcoded "sha256" applied to an ed25519 key; RFC 8032 keys generated by ssh-keygen or WebCrypto fed into RSA-era signing code.
Common situations: Migrating an RSA or ECDSA signing path to ed25519 while keeping the digest argument; JWT/JOSE libraries where RS256-era code calls one-shot sign with a fixed hash; key-agnostic utility functions that always pass a digest.
Related errors
- ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE
- ERR_CRYPTO_INVALID_JWK
- Invalid key type
- ERR_INVALID_ARG_VALUE
- Invalid digest: ${algorithm}
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/cc9df99ae108d4a2.
Report an issue: GitHub.