{"record":{"id":"fbf933c155e3beba","repo":"dgraph-io/dgraph","slug":"error-parsing-acl-key-as-ecdsa-private-key","errorCode":null,"errorMessage":"error parsing ACL key as ECDSA private key","messagePattern":"error parsing ACL key as ECDSA private key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"x/acl_enc_keys.go","lineNumber":107,"sourceCode":"\t\t}\n\n\t\tkeys.AclJwtAlg = aclAlg\n\t\tkeys.AclSecretKey = privKey\n\t\tkeys.AclPublicKey = pubKey\n\t}\n\n\treturn keys, nil\n}\n\nfunc parseJWTKey(alg jwt.SigningMethod, key Sensitive) (interface{}, interface{}, error) {\n\tswitch {\n\tcase strings.HasPrefix(alg.Alg(), \"HS\"):\n\t\treturn key, key, nil\n\n\tcase strings.HasPrefix(alg.Alg(), \"ES\"):\n\t\tpk, err := jwt.ParseECPrivateKeyFromPEM(key)\n\t\tif err != nil {\n\t\t\treturn nil, nil, errors.Wrapf(err, \"error parsing ACL key as ECDSA private key\")\n\t\t}\n\t\treturn pk, &pk.PublicKey, nil\n\n\tcase strings.HasPrefix(alg.Alg(), \"RS\") || strings.HasPrefix(alg.Alg(), \"PS\"):\n\t\tpk, err := jwt.ParseRSAPrivateKeyFromPEM(key)\n\t\tif err != nil {\n\t\t\treturn nil, nil, errors.Wrapf(err, \"error parsing ACL key as RSA private key\")\n\t\t}\n\t\treturn pk, &pk.PublicKey, nil\n\n\tcase alg.Alg() == \"EdDSA\":\n\t\tpk, err := jwt.ParseEdPrivateKeyFromPEM(key)\n\t\tif err != nil {\n\t\t\treturn nil, nil, errors.Wrapf(err, \"error parsing ACL key as EdDSA private key\")\n\t\t}\n\t\treturn pk.(crypto.Signer), pk.(ed25519.PrivateKey).Public(), nil\n\n\tdefault:","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/x/acl_enc_keys.go#L89-L125","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Generate a proper ECDSA private key PEM (openssl ecparam -name prime256v1 -genkey -noout -out acl_es.pem)","Or switch jwt-alg to HS256/HS384/HS512 if you intend to use a symmetric secret","Verify the PEM begins with '-----BEGIN EC PRIVATE KEY-----' or '-----BEGIN PRIVATE KEY-----'","Check the wrapped err for the underlying parse failure detail"],"exampleFix":"// before\njwt-alg=ES256 with hmac-secret=mysharedsecret\n// after\nopenssl ecparam -name prime256v1 -genkey -noout -out acl.pem; jwt-alg=ES256 with hmac-secret-file=/path/acl.pem","handlingStrategy":"validation","validationCode":"pemBytes, _ := os.ReadFile(keyPath)\nif !strings.Contains(string(pemBytes), \"BEGIN\") ||\n   !(strings.Contains(string(pemBytes), \"EC PRIVATE KEY\") || strings.Contains(string(pemBytes), \"PRIVATE KEY\")) {\n    return fmt.Errorf(\"%s is not an EC private key PEM; required for ES* algs\", keyPath)\n}","typeGuard":null,"tryCatchPattern":"if _, err := x.GetEncAclKeys(flag, encKey); err != nil {\n    if strings.Contains(err.Error(), \"error parsing ACL key as ECDSA private key\") {\n        log.Fatalf(\"key/algo mismatch: supply an ECDSA PEM for ES* or switch to HS256\")\n    }\n    return err\n}","preventionTips":["Match key type to algorithm: ECDSA key for ES*, RSA for RS*, Ed25519 for EdDSA, shared secret for HS*","Verify PEM headers before deployment","Never pass the public key or certificate where a private key is required"],"tags":["jwt","acl","crypto","ecdsa"],"backgroundTag":"jwt-key-format-mismatch","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}