TooTallNate/Java-WebSocket · error · IllegalArgumentException

Source array was null.

Error message

Source array was null.

What it means

decode4to3 is Base64's internal 4-byte-to-3-byte decoding step. It requires both a non-null source and destination array; a null source is rejected immediately with IllegalArgumentException. This is an internal precondition violated by a caller passing null input into a decode path.

Solutions

  1. Null-check the input byte[] before invoking any Base64 decode API.
  2. Treat a null payload as an empty result or an explicit error in your own code instead of forwarding it.
  3. If input is untrusted, validate at the API boundary and return a 400-style error rather than letting it propagate.

Example fix

// before
byte[] decoded = Base64.decode(data);

// after
byte[] decoded = (data == null) ? new byte[0] : Base64.decode(data);
Defensive patterns

Strategy: type-guard

Validate before calling

if (data != null) {
    byte[] decoded = Base64.decode(data);
} else {
    // treat as empty or surface a validation error
}

Type guard

static boolean isDecodable(byte[] input) {
    return input != null;
}

Try / catch

try {
    decoded = Base64.decode(data);
} catch (IllegalArgumentException e) {
    // null or malformed input
    decoded = null;
}

Prevention

When it happens

Trigger: A decode call chain (decode/decodeBytes/decodeFromFile wrappers) reaches decode4to3 with source == null — e.g. passing a null byte[] into a decode API that does not null-check earlier.

Common situations: Decoding a byte[] field read from config/database that is null; calling the deprecated decode(Object) style APIs with null; refactored code where an earlier null-check was removed.

Related errors


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

Appendix: source

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

   *
   * @param source      the array to convert
   * @param srcOffset   the index where conversion begins
   * @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==

View on GitHub (pinned to afeacbf8c0)