gchq/CyberChef · error · OperationError

Error: ${err.toString()}

Error message

Error: ${err.toString()}

What it means

Generic catch-all thrown by BcryptParse.run when bcrypt.getRounds(input) or bcrypt.getSalt(input) throws. The operation extracts the cost factor and salt from a bcrypt hash string; if the input is not a well-formed bcrypt hash, these accessors throw and the error is rewrapped as 'Error: <original>'. The operation is read-only metadata extraction, so any failure indicates the input is not a parseable bcrypt hash.

Source

Thrown at src/core/operations/BcryptParse.mjs:43

        this.infoURL = "https://wikipedia.org/wiki/Bcrypt";
        this.inputType = "string";
        this.outputType = "string";
        this.args = [];
    }

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     */
    async run(input, args) {
        try {
            return `Rounds: ${bcrypt.getRounds(input)}
Salt: ${bcrypt.getSalt(input)}
Password hash: ${input.split(bcrypt.getSalt(input))[1]}
Full hash: ${input}`;
        } catch (err) {
            throw new OperationError("Error: " + err.toString());
        }
    }

}

export default BcryptParse;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Provide a complete bcrypt hash string ($2a$/$2b$/$2y$ + cost + salt + hash).
  2. Trim surrounding whitespace/newlines before parsing.
  3. If you need to inspect a different algorithm's hash, use the corresponding analyser operation instead.

Example fix

// before - plain SHA hash
chef.bcryptParse("5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8");

// after - valid bcrypt hash
chef.bcryptParse("$2b$12$abcdefghijklmnopqrstuuVXQ1Nh2yTLB07h2yTLB07h2yTLB07h");
Defensive patterns

Strategy: validation

Validate before calling

const BCRYPT_HASH_RE = /^\$2[aby]\$\d{2}\$[./A-Za-z0-9]{53}$/;
function assertBcryptHash(hash) {
  const h = String(hash).trim();
  if (!BCRYPT_HASH_RE.test(h)) {
    throw new Error("Not a valid bcrypt hash; cannot parse rounds/salt");
  }
  return h;
}
assertBcryptHash(input);

Type guard

function isBcryptHash(s) {
  return /^\$2[aby]\$\d{2}\$[./A-Za-z0-9]{53}$/.test(String(s).trim());
}

Try / catch

try {
  await chef.bcryptParse(input);
} catch (e) {
  if (/invalid|illegal|not a valid/i.test(e.message)) {
    throw new Error(`Input is not a bcrypt hash: ${e.message}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Input that is not a bcrypt hash (no $2a/$2b/$2y prefix, missing cost field, invalid base64 salt, or a plain password/different-algorithm hash).

Common situations: Pasting an MD5/SHA-256 hash expecting to 'parse' it; hash copied without the version/cost prefix; whitespace or newline padding around the hash.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/4a3086579cb85176. Report an issue: GitHub.