grafana/k6 · error

key derivation not implemented for algorithm %s

Error message

key derivation not implemented for algorithm %s

What it means

Returned when crypto.subtle.deriveKey is called with a base algorithm k6 does not implement. newKeyDeriver (internal/js/modules/k6/webcrypto/key.go:230) supports only PBKDF2, so any other normalized algorithm name — ECDH, HKDF, or a misspelling — hits the default branch and the deriveKey promise rejects with 'key derivation not implemented for algorithm <name>'. Note that deriveBits has its own deriver and does support ECDH, so deriveKey is the narrower API.

Source

Thrown at internal/js/modules/k6/webcrypto/key.go:230

type KeyDeriver interface {
	DeriveKey(
		privateKey *CryptoKey,
		ki KeyImporter,
		kgl KeyGetLengther,
		keyUsages []CryptoKeyUsage,
		extractable bool,
	) (*CryptoKey, error)
}

func newKeyDeriver(rt *sobek.Runtime, normalized Algorithm, params sobek.Value) (KeyDeriver, error) {
	var kd KeyDeriver
	var err error

	switch normalized.Name {
	case PBKDF2:
		kd, err = newPBKDF2DeriveParams(rt, normalized, params)
	default:
		return nil, errors.New("key derivation not implemented for algorithm " + normalized.Name)
	}

	if err != nil {
		return nil, err
	}

	return kd, nil
}

// KeyGetLengther is the interface implemented by the parameters used to
// get the key length of cryptographic keys
type KeyGetLengther interface {
	GetKeyLength() int
}

func newKeyGetLengther(rt *sobek.Runtime, normalized Algorithm, params sobek.Value) (KeyGetLengther, error) {
	var kgi KeyGetLengther
	var err error

View on GitHub (pinned to 01ffac6f24)

Solutions

  1. For password-based derivation, switch to PBKDF2: crypto.subtle.deriveKey({ name: 'PBKDF2', salt, iterations: 100000, hash: 'SHA-256' }, passwordKey, derived, extractable, usages)
  2. For ECDH or HKDF material, replace deriveKey with deriveBits followed by importKey: const bits = await crypto.subtle.deriveBits(alg, baseKey, 256); const key = await crypto.subtle.importKey('raw', bits, { name: 'AES-GCM', length: 256 }, false, ['encrypt'])
  3. Check the algorithm name spelling — it must normalize to exactly 'PBKDF2'
  4. Track the grafana/xk6-webcrypto repository for ECDH/HKDF deriveKey support and upgrade k6 when it lands

Example fix

// before (ECDH deriveKey — unsupported)
const aesKey = await crypto.subtle.deriveKey(
  { name: 'ECDH', public: peerPublic }, myPrivate,
  { name: 'AES-GCM', length: 256 }, false, ['encrypt']);

// after (deriveBits + importKey)
const bits = await crypto.subtle.deriveBits(
  { name: 'ECDH', public: peerPublic }, myPrivate, 256);
const aesKey = await crypto.subtle.importKey(
  'raw', bits, { name: 'AES-GCM', length: 256 }, false, ['encrypt']);
Defensive patterns

Strategy: fallback

Validate before calling

const DERIVE_KEY_BASE_ALGORITHMS = new Set(['PBKDF2']);

async function deriveKeyCompat(algorithm, baseKey, derivedKeyType, extractable, usages) {
  if (DERIVE_KEY_BASE_ALGORITHMS.has(algorithm.name)) {
    return crypto.subtle.deriveKey(algorithm, baseKey, derivedKeyType, extractable, usages);
  }
  // k6 deriveKey only supports PBKDF2 — fall back to deriveBits + importKey
  const bits = await crypto.subtle.deriveBits(algorithm, baseKey, derivedKeyType.length);
  return crypto.subtle.importKey('raw', bits, derivedKeyType, extractable, usages);
}

Try / catch

try {
  key = await crypto.subtle.deriveKey(alg, baseKey, derived, extractable, usages);
} catch (err) {
  if (/key derivation not implemented/.test(String(err))) {
    const bits = await crypto.subtle.deriveBits(alg, baseKey, derived.length);
    key = await crypto.subtle.importKey('raw', bits, derived, extractable, usages);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: crypto.subtle.deriveKey({ name: 'ECDH', public: peerPublic }, myPrivate, { name: 'AES-GCM', length: 256 }, false, ['encrypt']) or crypto.subtle.deriveKey({ name: 'HKDF', hash: 'SHA-256', salt, info }, ikm, ...) — both reject with this message. A typo like 'PBKDF' also lands here because normalization must yield exactly 'PBKDF2'.

Common situations: Porting browser or Node.js WebCrypto code that supports ECDH/HKDF deriveKey and assuming k6 covers the same surface; password-based scripts where the algorithm string was changed; scripts written against xk6-webcrypto versions older than the integrated module.

Related errors


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/e2a50ad4ed8c0a54. Report an issue: GitHub.