dgraph-io/dgraph · error

error parsing ACL key as ECDSA private key

Error message

error parsing ACL key as ECDSA private key

What it means

parseJWTKey, called from GetEncAclKeys, dispatches on the JWT signing algorithm. For ES* algorithms the ACL key bytes must be a PEM-encoded ECDSA private key; jwt.ParseECPrivateKeyFromPEM failing (bad PEM, wrong key type, encrypted key) is wrapped in this error.

Source

Thrown at x/acl_enc_keys.go:107

		}

		keys.AclJwtAlg = aclAlg
		keys.AclSecretKey = privKey
		keys.AclPublicKey = pubKey
	}

	return keys, nil
}

func parseJWTKey(alg jwt.SigningMethod, key Sensitive) (interface{}, interface{}, error) {
	switch {
	case strings.HasPrefix(alg.Alg(), "HS"):
		return key, key, nil

	case strings.HasPrefix(alg.Alg(), "ES"):
		pk, err := jwt.ParseECPrivateKeyFromPEM(key)
		if err != nil {
			return nil, nil, errors.Wrapf(err, "error parsing ACL key as ECDSA private key")
		}
		return pk, &pk.PublicKey, nil

	case strings.HasPrefix(alg.Alg(), "RS") || strings.HasPrefix(alg.Alg(), "PS"):
		pk, err := jwt.ParseRSAPrivateKeyFromPEM(key)
		if err != nil {
			return nil, nil, errors.Wrapf(err, "error parsing ACL key as RSA private key")
		}
		return pk, &pk.PublicKey, nil

	case alg.Alg() == "EdDSA":
		pk, err := jwt.ParseEdPrivateKeyFromPEM(key)
		if err != nil {
			return nil, nil, errors.Wrapf(err, "error parsing ACL key as EdDSA private key")
		}
		return pk.(crypto.Signer), pk.(ed25519.PrivateKey).Public(), nil

	default:

View on GitHub (pinned to 759e242be6)

Solutions

  1. Generate a proper ECDSA private key PEM (openssl ecparam -name prime256v1 -genkey -noout -out acl_es.pem)
  2. Or switch jwt-alg to HS256/HS384/HS512 if you intend to use a symmetric secret
  3. Verify the PEM begins with '-----BEGIN EC PRIVATE KEY-----' or '-----BEGIN PRIVATE KEY-----'
  4. Check the wrapped err for the underlying parse failure detail

Example fix

// before
jwt-alg=ES256 with hmac-secret=mysharedsecret
// after
openssl ecparam -name prime256v1 -genkey -noout -out acl.pem; jwt-alg=ES256 with hmac-secret-file=/path/acl.pem
Defensive patterns

Strategy: validation

Validate before calling

pemBytes, _ := os.ReadFile(keyPath)
if !strings.Contains(string(pemBytes), "BEGIN") ||
   !(strings.Contains(string(pemBytes), "EC PRIVATE KEY") || strings.Contains(string(pemBytes), "PRIVATE KEY")) {
    return fmt.Errorf("%s is not an EC private key PEM; required for ES* algs", keyPath)
}

Try / catch

if _, err := x.GetEncAclKeys(flag, encKey); err != nil {
    if strings.Contains(err.Error(), "error parsing ACL key as ECDSA private key") {
        log.Fatalf("key/algo mismatch: supply an ECDSA PEM for ES* or switch to HS256")
    }
    return err
}

Prevention

When it happens

Trigger: Using an ES256/ES384/ES512 jwt-alg while the ACL secret file/vault value contains an HMAC secret, an RSA key, a public key, or malformed/non-PEM data.

Common situations: Reusing an HS256 shared secret with an ECDSA algorithm; exporting the public .pem instead of the private key; key file containing raw bytes instead of PEM.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/fbf933c155e3beba. Report an issue: GitHub.