TooTallNate/Java-WebSocket · error · IllegalArgumentException

Destination array was null.

Error message

Destination array was null.

What it means

decode4to3 also requires a non-null destination array to write the 3 decoded bytes into. A null destination throws IllegalArgumentException immediately. This normally indicates a null output buffer passed down from a public decode method.

Solutions

  1. Ensure the destination array is allocated (new byte[...]) before calling the decode API.
  2. Check argument order — source and destination were likely swapped.
  3. Add a null assert/guard before invoking decode if the buffer comes from a pool or lazy allocation.

Example fix

// before
byte[] dest = null;
Base64.decodeBytes(src, 0, src.length, dest, 0);

// after
byte[] dest = new byte[Base64.decodeBytesToBytes(src, 0, src.length).length];
Base64.decode(src, 0, src.length, dest, 0);
Defensive patterns

Strategy: type-guard

Validate before calling

if (src != null && dest != null) {
    Base64.decode(src, 0, src.length, dest, 0);
}

Type guard

static boolean hasBuffers(byte[] src, byte[] dest) {
    return src != null && dest != null;
}

Try / catch

try {
    Base64.decode(src, 0, src.length, dest, 0);
} catch (IllegalArgumentException e) {
    // destination was null or too small
    throw new IllegalStateException("decode output buffer not initialized", e);
}

Prevention

When it happens

Trigger: A decode variant that takes an explicit destination byte[] (e.g. decode(source, offset, length, options) style overloads or decodeBytes with output buffer) is given a null destination.

Common situations: Reusing a buffer variable that was never initialized; a lazily-allocated output buffer that was still null when decoding was attempted; API misuse where the user confused source and destination parameters.

Related errors


AI-assisted analysis of TooTallNate/Java-WebSocket@afeacbf8c0 (2026-09-09). Data as JSON: /api/errors/6d07de013ea096eb. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/org/java_websocket/util/Base64.java:811

   * @param destination the array to hold the conversion
   * @param destOffset  the index where output will be put
   * @param options     alphabet type is pulled from this (standard, url-safe, ordered)
   * @return the number of decoded bytes converted
   * @throws IllegalArgumentException if source or destination arrays are null, if srcOffset or
   *                                  destOffset are invalid or there is not enough room in the
   *                                  array.
   * @since 1.3
   */
  private static int decode4to3(
      byte[] source, int srcOffset,
      byte[] destination, int destOffset, int options) {

    // Lots of error checking and exception throwing
    if (source == null) {
      throw new IllegalArgumentException("Source array was null.");
    }   // end if
    if (destination == null) {
      throw new IllegalArgumentException("Destination array was null.");
    }   // end if
    if (srcOffset < 0 || srcOffset + 3 >= source.length) {
      throw new IllegalArgumentException(String.format(
          "Source array with length %d cannot have offset of %d and still process four bytes.",
          source.length, srcOffset));
    }   // end if
    if (destOffset < 0 || destOffset + 2 >= destination.length) {
      throw new IllegalArgumentException(String.format(
          "Destination array with length %d cannot have offset of %d and still store three bytes.",
          destination.length, destOffset));
    }   // end if

    final byte[] DECODABET = getDecodabet(options);

    // Example: Dk==
    if (source[srcOffset + 2] == EQUALS_SIGN) {
      // Two ways to do the same thing. Don't know which way I like best.
      //int outBuff =   ( ( DECODABET[ source[ srcOffset    ] ] << 24 ) >>>  6 )

View on GitHub (pinned to afeacbf8c0)