grafana/k6 · error
encrypted pkcs8 formatted key is not supported
Error message
encrypted pkcs8 formatted key is not supported
What it means
k6's encrypted-key decryption uses the legacy x509.DecryptPEMBlock API, which only understands traditional OpenSSL PEM encryption. Keys with block type 'ENCRYPTED PRIVATE KEY' (PKCS#8, e.g. PBES2 output of openssl pkcs8 -topk8 / genpkey with a passphrase) are explicitly rejected before decryption is attempted.
Source
Thrown at internal/js/modules/k6/grpc/client.go:133
fdset := &descriptorpb.FileDescriptorSet{}
if err = proto.Unmarshal(fdsetBytes, fdset); err != nil {
return nil, fmt.Errorf("couldn't unmarshal protoset file %s: %w", protosetPath, err)
}
return c.convertToMethodInfo(fdset)
}
// Note: this function was lifted from `lib/options.go`
func decryptPrivateKey(key, password []byte) ([]byte, error) {
block, _ := pem.Decode(key)
if block == nil {
return nil, errors.New("failed to decode PEM key")
}
blockType := block.Type
if blockType == "ENCRYPTED PRIVATE KEY" {
return nil, errors.New("encrypted pkcs8 formatted key is not supported")
}
/*
Even though `DecryptPEMBlock` has been deprecated since 1.16.x it is still
being used here because it is deprecated due to it not supporting *good* cryptography
ultimately though we want to support something so we will be using it for now.
*/
decryptedKey, err := x509.DecryptPEMBlock(block, password) //nolint:staticcheck
if err != nil {
return nil, err
}
key = pem.EncodeToMemory(&pem.Block{
Type: blockType,
Bytes: decryptedKey,
})
return key, nil
}
func buildTLSConfig(parentConfig *tls.Config, certificate, key []byte, caCertificates [][]byte) (*tls.Config, error) {View on GitHub (pinned to 93accf6570)
Solutions
- Decrypt to an unencrypted key: openssl pkcs8 -in key.enc.pem -nodes -out key.pem
- Or convert to traditional RSA PEM encryption: openssl rsa -in key.enc.pem -aes256 -out key.trad.pem (then pass the new password)
- Long-term: track the upstream k6 issue for PKCS#8 support instead of working around per script
Example fix
# before: key has '-----BEGIN ENCRYPTED PRIVATE KEY-----'
# after: produce a supported format
openssl pkcs8 -in key.enc.pem -nodes -out key.pem
# then connect without a password for that cert pair:
client.connect(addr, { tls: { certs: [[certPem, keyPem]] } }); Defensive patterns
Strategy: validation
Validate before calling
function isEncryptedPkcs8(pem) {
return pem.trim().startsWith('-----BEGIN ENCRYPTED PRIVATE KEY-----');
}
if (isEncryptedPkcs8(keyPem)) {
throw new Error('k6 does not support encrypted PKCS#8 keys; convert with: openssl pkcs8 -in key.pem -nodes -out key-decrypted.pem');
} Prevention
- Standardize team keys on unencrypted PEM or traditional RSA PEM encryption
- Inspect the BEGIN header of any key generated by openssl genpkey/pkcs8 -topk8
- Decrypt copies used for load testing and keep the encrypted originals in the secret store
When it happens
Trigger: client.connect(addr, { tls: { certs: [[cert, key, password]] } }) where key is an encrypted PKCS#8 file (header -----BEGIN ENCRYPTED PRIVATE KEY-----).
Common situations: Keys provisioned by modern openssl defaults (genpkey + pkcs8 -topk8), cloud KMS exports, or company PKI tooling that standardizes on PKCS#8 encryption.
Related errors
- failed to decode PEM key
- failed to append ca certificate [%d] from PEM
- failed to append root certificate to the pool
- failed to create dial options: %w
- failed to dial: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/d88664efcaa44fa4.
Report an issue: GitHub.