FuelLabs/fuels-ts · error · FuelError

INVALID_ENTROPY

INVALID_ENTROPY

Error message

Entropy should be between 16 and 32 bytes and a multiple of 4, but got ${entropy.length} bytes.

What it means

Thrown by assertEntropy when entropy passed to mnemonic generation violates BIP-39 size rules. Valid entropy must be a multiple of 4 bytes and fall in the 16–32 byte range (i.e. 16, 20, 24, 28, or 32 bytes), which correspond to the 12/15/18/21/24-word mnemonics. The library enforces this so that the resulting mnemonic has a mathematically valid checksum length.

Source

Thrown at packages/account/src/mnemonic/mnemonic.ts:33

// "Bitcoin seed"
const MasterSecret = toUtf8Bytes('Bitcoin seed');
// 4 byte: version bytes (mainnet: 0x0488B21E public, 0x0488ADE4 private; testnet: 0x043587CF public, 0x04358394 private)
const MainnetPRV = '0x0488ade4';
const TestnetPRV = '0x04358394';
export const MNEMONIC_SIZES = [12, 15, 18, 21, 24];

function assertWordList(wordlist: Array<string>) {
  if (wordlist.length !== 2048) {
    throw new FuelError(
      ErrorCode.INVALID_WORD_LIST,
      `Expected word list length of 2048, but got ${wordlist.length}.`
    );
  }
}

function assertEntropy(entropy: BytesLike) {
  if (entropy.length % 4 !== 0 || entropy.length < 16 || entropy.length > 32) {
    throw new FuelError(
      ErrorCode.INVALID_ENTROPY,
      `Entropy should be between 16 and 32 bytes and a multiple of 4, but got ${entropy.length} bytes.`
    );
  }
}

function assertMnemonic(words: Array<string>) {
  if (!MNEMONIC_SIZES.includes(words.length)) {
    const errorMsg = `Invalid mnemonic size. Expected one of [${MNEMONIC_SIZES.join(
      ', '
    )}] words, but got ${words.length}.`;

    throw new FuelError(ErrorCode.INVALID_MNEMONIC, errorMsg);
  }
}

class Mnemonic {
  wordlist: Array<string>;

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Ensure entropy is exactly 16, 20, 24, 28, or 32 bytes (32/40/48/56/64 hex characters respectively).
  2. If you need a random mnemonic, call Mnemonic.generateMnemonic() with no entropy so the library generates a correctly-sized buffer.
  3. Pad/truncate an existing seed only if you understand the security implications, and re-verify the length with entropy.length before passing it.
  4. If deriving entropy from another source, slice to a valid length: e.g. entropy.slice(0, 32) for a 24-word mnemonic.

Example fix

// before
const phrase = Mnemonic.entropyToMnemonic('0x00112233445566'); // 7 bytes

// after
const entropy = randomBytes(16); // valid: 16 bytes -> 12 words
const phrase = Mnemonic.entropyToMnemonic(entropy);
Defensive patterns

Strategy: validation

Validate before calling

import { arrayify } from '@fuel-ts/utils';
const VALID_ENTROPY_LENGTHS = new Set([16, 20, 24, 28, 32]);
function assertValidEntropy(entropy: Uint8Array | string) {
  const bytes = typeof entropy === 'string' ? arrayify(entropy) : entropy;
  if (!VALID_ENTROPY_LENGTHS.has(bytes.length)) {
    throw new Error(`Entropy must be 16/20/24/28/32 bytes; got ${bytes.length}`);
  }
}
// call before Mnemonic.entropyToMnemonic(entropy)

Type guard

function isValidEntropy(bytes: Uint8Array): bytes is Uint8Array {
  return bytes.length >= 16 && bytes.length <= 32 && bytes.length % 4 === 0;
}

Try / catch

import { FuelError, ErrorCode } from '@fuel-ts/errors';
try {
  const phrase = Mnemonic.entropyToMnemonic(entropy);
} catch (e) {
  if (e instanceof FuelError && e.code === ErrorCode.INVALID_ENTROPY) {
    // surface a user-facing message about valid entropy sizes
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling Mnemonic.entropyToMnemonic(entropy) or Mnemonic.generateMnemonic(entropy) with entropy whose byte length is not in {16,20,24,28,32}; passing a hex string or Uint8Array that is e.g. 15, 17, or 33 bytes; passing 12 bytes (too short) or 36 bytes (too long).

Common situations: Generating a wallet from a hand-picked entropy buffer; truncating/padding a key incorrectly before seeding a mnemonic; migrating from a library that did not enforce the multiple-of-4 rule; copying a 32-character hex string (16 chars = 8 bytes, mistaken as 16 bytes).

Related errors


AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12). Data as JSON: /api/errors/59afe8bb2c3f8b13. Report an issue: GitHub.