"Wrong email or password" after bulk user import

I am trying to bulk import users to Auth0. We don’t use their standard hashing algorithm, so I’ve had to convert our hashes to fit their “custom_password_hash” requirements. However, when I try to log in as one of those users, the Auth0 gives an incorrect password error.

Here is how we were generating salts and hashes pre Auth0:

var salt = crypto.randomBytes(32).toString('hex');
var hash = crypto
    .pbkdf2Sync(password, salt, 10000, 64, 'sha512')

Here is how I am creating the custom_password_hash object Auth0 requests for each user to be imported:

const phcobj = {
    id: 'pbkdf2-sha256',
    params: {i: 10000, l: 64},
    salt: Buffer.from(salt, 'base64'), // create a binary buffer from base64 encoded string
    hash: Buffer.from(hash, 'base64'), 
  const serialized = phc.serialize(phcobj);
  return {
    "algorithm": 'pbkdf2',
    "hash": {
      "value": serialized,
      "encoding": "utf8"

I am following the requirements for pbkdf2 hashes described here: Bulk User Import Database Schema and Examples

I am able to successfully import users via the Auth0 import/export extension. The users appear in the user management section (though without any password appearing in “raw json”, but maybe this is normal.

But when I go to log in, I get an error “Wrong email or password”. This is unexpected. I should just be able to log in.

What am I missing?

1 Like

Additionally, the user_id I imported is not reflected on the user once imported (according to my “users” tab).

I’m also getting same issue did you fix it???

heyyyy , @rueben.tiow need some help here ! going through same issue need some assist. not able to login with migrated users

Ran into this issue today and what the api needs is base64url encoded salt and hash, not hex encoded as shown in the “pre Auth0” example above. In our db we had hex encoded hashes and base64url encoded salts, so the hashes needed to be re-encoded as base64url before sending to Auth0.

Example js code to generate a password that Auth0 will process correctly:

const phc = require('@phc/format');
const crypto = require('node:crypto');

const password = 'password';
const salt = crypto.randomBytes(16);
const keylen = 32;
const iterations = 260000;
const digest = 'sha256';

const hash = crypto.pbkdf2Sync(password, salt, iterations, keylen, digest);

const phcobj = {
  id: `pbkdf2-${digest}`,
  params: {i: iterations, l: keylen},

const phcstr = phc.serialize(phcobj).toString('utf-8');

Actual json to send to the users-imports endpoint:

    "email": "text@example.com",
    "custom_password_hash": {
      "algorithm": "pbkdf2",
      "hash": {
        "value": "$pbkdf2-sha256$i=260000,l=32$vHHCR+yr7MNdL/zoVHz56g$l1jPurS8vNa4yF504zdFxh5K+yWpNQGhah7I28f/Zbw",
        "encoding": "utf8"

hey @sleepylemur thanks this works . Can you do the same for sha256 ???

1 Like

glad it works. we’re only importing pbkdf2-sha256 and i don’t have bandwidth to explore the other accepted formats. best of luck!

Update: I believe it is actually base64 encoded, not base64url encoded for both salt and hash.