dgraph-io/dgraph · error

error parsing ACL key as EdDSA private key

Error message

error parsing ACL key as EdDSA private key

What it means

For the EdDSA algorithm, parseJWTKey calls jwt.ParseEdPrivateKeyFromPEM, which requires a PEM-encoded Ed25519 private key. Failure to parse is wrapped in this error; a successful parse also requires the key to be castable to ed25519.PrivateKey.

Source

Thrown at x/acl_enc_keys.go:121

	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:
		return nil, nil, errors.Errorf("unsupported signing algorithm: %v", alg.Alg())
	}
}

func checkAclKeyLength(alg jwt.SigningMethod, key Sensitive) error {
	if !strings.HasPrefix(alg.Alg(), "HS") {
		return nil
	}

	sl, err := strconv.Atoi(strings.TrimPrefix(alg.Alg(), "HS"))
	if err != nil {
		return errors.Wrapf(err, "error finding sha length for algo %v", alg.Alg())
	}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Generate an Ed25519 private key as PKCS#8 PEM (openssl genpkey -algorithm ed25519 -out acl_ed.pem)
  2. Or change jwt-alg to HS256/RS256 to match the key you already have
  3. Ensure the key file contains full PEM blocks, not raw key bytes
  4. Confirm the vendored golang-jwt version supports EdDSA parsing

Example fix

// before
echo -n "raw32byteskey..." > acl.key; jwt-alg=EdDSA
// after
openssl genpkey -algorithm ed25519 -out acl.pem; jwt-alg=EdDSA with hmac-secret-file=/path/acl.pem
Defensive patterns

Strategy: validation

Validate before calling

pemBytes, _ := os.ReadFile(keyPath)
if alg == "EdDSA" {
    if _, err := jwt.ParseEdPrivateKeyFromPEM(pemBytes); err != nil {
        return fmt.Errorf("need PKCS#8 Ed25519 private key PEM: %w", err)
    }
}

Try / catch

if _, err := x.GetEncAclKeys(flag, encKey); err != nil {
    if strings.Contains(err.Error(), "error parsing ACL key as EdDSA private key") {
        log.Fatalf("generate with: openssl genpkey -algorithm ed25519")
    }
    return err
}

Prevention

When it happens

Trigger: Setting jwt-alg=EdDSA while the ACL key is not an Ed25519 private key PEM (e.g. RSA, ECDSA, HMAC secret, or raw 32 bytes without PEM encoding).

Common situations: Generating an ed25519 key with a tool that outputs raw or OpenSSH-format keys not accepted as PKCS#8 PEM; reusing a key from a different algorithm configuration.

Related errors


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