alibaba/COLA · error · IllegalArgumentException

random cannot be null.

Error message

random cannot be null.

What it means

UuidGenerator.randomNanoId(Random, char[], int) validates its arguments and throws IllegalArgumentException when the supplied Random is null. This is a NanoId-style generator ported into cola-job; the null check is a standard precondition.

Source

Thrown at cola-components/cola-component-job/src/main/java/com/alibaba/cola/job/UuidGenerator.java:64

    /**
     * 生成随机的NanoId工具内部类
     */
    public final class NanoIdUtils {
        public static final SecureRandom DEFAULT_NUMBER_GENERATOR = new SecureRandom();
        public static final char[] DEFAULT_ALPHABET = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
        public static final int DEFAULT_SIZE = 21;

        private NanoIdUtils() {
        }

        public static String randomNanoId() {
            return randomNanoId(DEFAULT_NUMBER_GENERATOR, DEFAULT_ALPHABET, 21);
        }

        public static String randomNanoId(Random random, char[] alphabet, int size) {
            if (random == null) {
                throw new IllegalArgumentException("random cannot be null.");
            } else if (alphabet == null) {
                throw new IllegalArgumentException("alphabet cannot be null.");
            } else if (alphabet.length != 0 && alphabet.length < 256) {
                if (size <= 0) {
                    throw new IllegalArgumentException("size must be greater than zero.");
                } else {
                    int mask = (2 << (int)Math.floor(Math.log((double)(alphabet.length - 1)) / Math.log(2.0D))) - 1;
                    int step = (int)Math.ceil(1.6D * (double)mask * (double)size / (double)alphabet.length);
                    StringBuilder idBuilder = new StringBuilder();

                    while(true) {
                        byte[] bytes = new byte[step];
                        random.nextBytes(bytes);

                        for(int i = 0; i < step; ++i) {
                            int alphabetIndex = bytes[i] & mask;
                            if (alphabetIndex < alphabet.length) {
                                idBuilder.append(alphabet[alphabetIndex]);

View on GitHub (pinned to 352e1a8675)

Solutions

  1. Pass a non-null Random, e.g. new SecureRandom()
  2. Use the no-arg randomNanoId() convenience overload which uses the default generator
  3. Fix the field/bean that should hold a Random instance but is null

Example fix

// before
String id = UuidGenerator.randomNanoId(null, alphabet, 21);
// after
String id = UuidGenerator.randomNanoId(new SecureRandom(), alphabet, 21);
Defensive patterns

Strategy: validation

Validate before calling

if (random == null) throw new IllegalArgumentException("supply a Random, e.g. new SecureRandom()");

Type guard

String safeNanoId(Random random, char[] alphabet, int size) {
    Random r = random != null ? random : new SecureRandom();
    return UuidGenerator.randomNanoId(r, alphabet != null ? alphabet : DEFAULT_ALPHABET, Math.max(1, size));
}

Try / catch

try {
    id = UuidGenerator.randomNanoId(random, alphabet, size);
} catch (IllegalArgumentException e) {
    log.warn("randomNanoId invalid argument: {}", e.getMessage());
    id = UuidGenerator.randomNanoId();
}

Prevention

When it happens

Trigger: Calling UuidGenerator.randomNanoId(null, alphabet, size) or indirectly passing a null Random from configuration or a factory.

Common situations: Passing an uninitialized SecureRandom field that was never assigned; a supplier of randomness returning null; copy-paste of the overload call with the wrong first argument.

Related errors


AI-assisted analysis of alibaba/COLA@352e1a8675 (2026-09-08). Data as JSON: /api/errors/cab74a04a5096a0e. Report an issue: GitHub.