Profiles·Public

bcrypt

semver>=5.0.0 <7.0.0postconditions25functions7last verified2026-06-24coverage score100%

Postconditions: what we check

  • hash · invalid-args
    error
    Whendata or salt is null/undefined, or data is not a string/Buffer, or salt is not a string or number
    ThrowsError with message 'data and salt arguments required' or 'data must be a string or Buffer and salt must either be a salt string or a number of rounds'
    Required handlingCaller MUST validate inputs before calling bcrypt.hash(). Wrap calls in try-catch (synchronous throw path) or use .catch() / try-await-catch for the Promise path. Unhandled rejections will crash the process in Node.js.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • hash · hashing-error
    error
    WhenAn error occurs during the native bcrypt hashing operation (e.g., native module failure)
    ThrowsError — rejected Promise or callback first argument
    Required handlingCaller MUST wrap bcrypt.hash() in try-catch when using async/await, or provide an error-checking callback. Unhandled rejections will crash the process.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • hash · hash-invalid-callback
    error
    WhenA third argument is passed as the callback but is not a function (e.g., a string, object, or number). Returns a rejected Promise regardless of whether data and salt are valid.
    ThrowsRejected Promise with Error('cb must be a function or null to return a Promise'). This is a programmer error — the rejection fires synchronously before any hashing occurs.
    Required handlingCaller MUST either omit the callback (use async/await) or ensure cb is a function. Passing a non-function third argument is a programming error that produces a rejected promise. Wrap the call in try-catch or handle with .catch().
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • hash · hash-callback-position-swap
    warning
    WhenThe first or second positional argument to bcrypt.hash() is itself a function (typeof === 'function'). Common cause: registration flows refactored from callback to promise style where the cb was left in the data or salt slot, or a helper that intended to return a salt value accidentally returns a function reference.
    ThrowsDoes NOT reject any Promise — none is constructed. bcrypt SYNCHRONOUSLY invokes the mispositioned function with Error('data must be a string or Buffer and salt must either be a salt string or a number of rounds') via process.nextTick. The return value of bcrypt.hash() is undefined; `await bcrypt.hash(fn, 10)` resolves to undefined. The Error reaches the misplaced function but not the await-scope try-catch.
    Required handlingCallers MUST validate that data is a string/Buffer BEFORE the call — a try-catch around `await bcrypt.hash(...)` will NOT catch this misuse. In a registration handler, the downstream symptom is that `await bcrypt.hash(plaintext, 10)` returns undefined, which then gets persisted to the user record as a null/undefined password hash. Subsequent login attempts route through bcrypt.compare(plaintext, undefined) and fail with a different error path — the original misuse is invisible at the registration site.
    costhighin prodsilent failureusers seelost datavisibilitysilent
    Sources[1]
  • hash · success
    info
    WhenHashing completes successfully
    ReturnsPromise<string> resolving to the bcrypt hash string (60 characters)
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • compare · invalid-args
    error
    Whendata or hash is null/undefined, or data is not a string/Buffer, or hash is not a string
    ThrowsAsync path (Promise): rejects with Error('data and hash arguments required') if either arg is null/undefined, or Error('data and hash must be strings') for type mismatches (v6.0.0 source line 211 — message differs from compareSync which still emits the longer 'data must be a string or Buffer and hash must be a string' form on line 166).
    Required handlingCaller MUST validate that both arguments are present and of the correct type. Wrap calls in try-catch or use .catch() on the returned Promise. Note: error.message text differs between sync and async paths in v6 — do not assert on exact message text across paths.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • compare · comparison-error
    error
    WhenAn error occurs during the native bcrypt comparison (e.g., malformed hash string)
    ThrowsError — rejected Promise or callback first argument
    Required handlingCaller MUST wrap bcrypt.compare() in try-catch when using async/await. A malformed hash string causes an error, not a false return value.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • compare · compare-invalid-callback
    error
    WhenA third argument is passed as the callback but is not a function (e.g., a string, object, or number). Returns a rejected Promise regardless of whether data and hash are valid.
    ThrowsRejected Promise with Error('cb must be a function or null to return a Promise'). This is a programmer error.
    Required handlingCaller MUST either omit the callback (use async/await) or ensure cb is a function. Wrap the call in try-catch or handle with .catch().
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • compare · compare-callback-position-swap
    warning
    WhenThe first or second positional argument to bcrypt.compare() is itself a function (typeof === 'function'). Common cause: callers refactoring from callback→promise styles who accidentally leave the callback in the data or hash slot, or callers passing an unawaited helper that returns a function.
    ThrowsDoes NOT reject any Promise — none is constructed. Instead, bcrypt SYNCHRONOUSLY invokes the mispositioned function with an Error('data and hash arguments required') via process.nextTick. The return value of bcrypt.compare() in this branch is undefined; `await bcrypt.compare(fn, hash)` resolves to undefined. The Error reaches the misplaced function but not the await-scope try-catch.
    Required handlingCallers MUST validate that both positional arguments are strings/Buffers BEFORE the call — a try-catch around `await bcrypt.compare(...)` will NOT catch this misuse. The downstream symptom in an auth check is silent rejection of valid credentials: `if (await bcrypt.compare(plaintext, storedHash))` evaluates the undefined return as falsy, denying access to users whose credentials would otherwise match. The misfired callback's Error lands in whichever scope owns the function value, which is rarely the auth-check scope.
    costmediumin prodsilent failureusers seeauthentication failurevisibilitysilent
    Sources[1]
  • compare · mismatch
    info
    WhenThe plain-text data does not match the hash
    ReturnsPromise<false> — resolves to boolean false
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • compare · match
    info
    WhenThe plain-text data matches the hash
    ReturnsPromise<true> — resolves to boolean true
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • genSalt · invalid-rounds
    error
    Whenrounds parameter is provided but is not a number
    ThrowsError with message 'rounds must be a number'
    Required handlingCaller MUST ensure rounds is a number when provided. Wrap in try-catch or use .catch() on the returned Promise.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • genSalt · invalid-minor
    error
    Whenminor version parameter is provided but is not 'a' or 'b'
    ThrowsError with message 'minor must be either a or b'
    Required handlingOnly pass 'a' or 'b' as the minor version. The default ('b') is recommended for new code.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • genSalt · gen-salt-entropy-error
    error
    WhenNode.js crypto.randomBytes() fails to generate random bytes — typically due to system entropy exhaustion in containerized or virtualized environments (rare but real in CI/CD and Docker).
    ThrowsRejected Promise (or callback error) with the Error from crypto.randomBytes(). Error message varies by OS — commonly 'Error generating random bytes' or similar.
    Required handlingCaller MUST wrap bcrypt.genSalt() in try-catch or use .catch(). While rare in production, entropy exhaustion is a known failure mode in ephemeral containers and edge deployments. In registration flows, a failure here means the user cannot create an account — treat as a retriable error.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][3]
  • genSalt · success
    info
    WhenSalt generation succeeds
    ReturnsPromise<string> resolving to the generated salt string
    Required handlingNo action required — use the returned value as needed.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • hashSync · hash-sync-invalid-args
    error
    Whendata or salt is null/undefined, or data is not a string/Buffer, or salt is not a string or number
    ThrowsError('data and salt arguments required') if either arg is null/undefined; Error('data must be a string or Buffer and salt must either be a salt string or a number of rounds') for type mismatches. Throws synchronously — not a rejected Promise.
    Required handlingCaller MUST validate inputs before calling bcrypt.hashSync(). Wrap in try-catch since this is a synchronous throw (not a rejected Promise). A missing try-catch will propagate the exception up the call stack — in Express, this crashes the request handler unless a global error boundary catches it.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • hashSync · hash-sync-event-loop-block
    warning
    WhenCalled in a web server request handler with saltRounds >= 10
    ThrowsDoes not throw — but blocks the Node.js event loop for 100ms–1s+ per call
    Required handlingDO NOT call bcrypt.hashSync() inside Express/Fastify/Next.js route handlers or any code on the request/response hot path. Use the async bcrypt.hash() instead. Blocking the event loop during password hashing causes ALL concurrent HTTP requests to queue, leading to cascading latency under load. This is a behavioral correctness issue, not just a performance concern.
    costhighin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[2]
  • compareSync · compare-sync-invalid-args
    error
    Whendata or hash is null/undefined, or data is not a string/Buffer, or hash is not a string
    ThrowsError('data and hash arguments required') if either arg is null/undefined; Error('data must be a string or Buffer and hash must be a string') for type mismatches. Throws synchronously.
    Required handlingCaller MUST validate inputs before calling bcrypt.compareSync(). Wrap in try-catch. A malformed hash string (e.g., not a valid bcrypt hash) will cause this function to throw — it does NOT return false for an invalid hash format.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • compareSync · compare-sync-event-loop-block
    warning
    WhenCalled in a web server request handler
    ThrowsDoes not throw — but blocks the Node.js event loop for 100ms–1s+ per call
    Required handlingDO NOT call bcrypt.compareSync() inside Express/Fastify/Next.js route handlers. Use bcrypt.compare() (async) instead. During login endpoints under load, using compareSync serializes all auth checks — each login queues behind the previous one, causing login latency to multiply linearly with concurrent users.
    costhighin proddegraded serviceusers seedegraded performancevisibilityvisible
    Sources[2]
  • genSaltSync · gen-salt-sync-invalid-rounds
    error
    Whenrounds parameter is provided but is not a number (e.g., a string)
    ThrowsError('rounds must be a number'). Throws synchronously.
    Required handlingCaller MUST ensure rounds is a number when provided. Wrap in try-catch. Note: falsy values (0, null, undefined) are silently coerced to the default 10 rounds — only non-number, truthy values throw.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • genSaltSync · gen-salt-sync-invalid-minor
    error
    Whenminor parameter is provided but is not 'a' or 'b'
    ThrowsError('minor must be either "a" or "b"'). Throws synchronously.
    Required handlingOnly pass 'a' or 'b' as the minor version. Omit the parameter to use the default 'b'. Passing any other string causes an immediate synchronous throw.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • genSaltSync · gen-salt-sync-success
    info
    WhenSalt generation succeeds
    Returnsstring — a bcrypt salt in the format '$2b$<rounds>$<22-char-base64-salt>' (29 characters total). This salt string is passed directly to bcrypt.hashSync().
    Required handlingNo action required — use the returned salt string as input to hashSync() or hash().
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • getRounds · get-rounds-missing-hash
    error
    Whenhash argument is null or undefined
    ThrowsError('hash argument required'). Throws synchronously.
    Required handlingCaller MUST check that the hash argument exists before calling getRounds(). Wrap in try-catch. Common failure pattern: calling getRounds() during hash migration/audit over DB rows where some rows have null password fields.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • getRounds · get-rounds-invalid-type
    error
    Whenhash argument is not a string (e.g., a Buffer or number)
    ThrowsError('hash must be a string'). Throws synchronously.
    Required handlingCaller MUST ensure the hash is a string. Wrap in try-catch. Common failure pattern: passing a Buffer or TypeScript typed value that hasn't been .toString()'d before passing to getRounds().
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • getRounds · get-rounds-success
    info
    Whenhash argument is a valid bcrypt hash string
    Returnsnumber — the integer cost factor (rounds) embedded in the hash string. Extracted from the hash format: '$2b$<cost>$...'. For most production hashes, returns 10-12.
    Required handlingNo action required. Compare the returned number against your current minimum rounds policy (e.g., if returned value < 12, trigger a rehash on next login to upgrade security).
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Official documentation
  • [3]
    nodejs.org/api/crypto.html
    Crypto
Source code

Research notes

Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.

Sources: bcrypt

Official Documentation

Research Date: 2026-02-26

Need a different package?
Request a profile