apache/flink · error · NullPointerException

Byte array to deserialize from must not be null.

Error message

Byte array to deserialize from must not be null.

What it means

First overload of InstantiationUtil.deserializeFromByteArray(serializer, buf): it requires a non-null byte array and throws NullPointerException('Byte array to deserialize from must not be null.') otherwise. It then wraps buf in a DataInputViewStreamWrapper and calls serializer.deserialize — so the null check is the only pre-validation; a zero-length or corrupt array surfaces as whatever the serializer throws.

Source

Thrown at flink-core/src/main/java/org/apache/flink/util/InstantiationUtil.java:446

        config.setBytes(key, bytes);
    }

    public static <T> byte[] serializeToByteArray(TypeSerializer<T> serializer, T record)
            throws IOException {
        if (record == null) {
            throw new NullPointerException("Record to serialize to byte array must not be null.");
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream(64);
        DataOutputViewStreamWrapper outputViewWrapper = new DataOutputViewStreamWrapper(bos);
        serializer.serialize(record, outputViewWrapper);
        return bos.toByteArray();
    }

    public static <T> T deserializeFromByteArray(TypeSerializer<T> serializer, byte[] buf)
            throws IOException {
        if (buf == null) {
            throw new NullPointerException("Byte array to deserialize from must not be null.");
        }

        DataInputViewStreamWrapper inputViewWrapper =
                new DataInputViewStreamWrapper(new ByteArrayInputStream(buf));
        return serializer.deserialize(inputViewWrapper);
    }

    public static <T> T deserializeFromByteArray(TypeSerializer<T> serializer, T reuse, byte[] buf)
            throws IOException {
        if (buf == null) {
            throw new NullPointerException("Byte array to deserialize from must not be null.");
        }

        DataInputViewStreamWrapper inputViewWrapper =
                new DataInputViewStreamWrapper(new ByteArrayInputStream(buf));
        return serializer.deserialize(reuse, inputViewWrapper);
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Null-check the byte array at the source and supply empty/absent semantics explicitly
  2. Use Configuration.containsKey/getOptional so absent values never reach deserialization as null
  3. When storing optional payloads, write a presence flag (or use empty byte[0]) instead of null

Example fix

// before
byte[] bytes = config.getBytes(key);
T value = InstantiationUtil.deserializeFromByteArray(ser, bytes);
// after
byte[] bytes = config.getBytes(key);
T value = (bytes == null) ? null : InstantiationUtil.deserializeFromByteArray(ser, bytes);
Defensive patterns

Strategy: validation

Validate before calling

if (bytes == null) return defaultValue; // before calling deserializeFromByteArray

Prevention

When it happens

Trigger: Calling deserializeFromByteArray(serializer, null) — e.g. reading an optional field from state/config where the key was absent and getBytes returned null, or a map lookup that missed.

Common situations: Configuration round-trips where writeObjectToConfig never ran; absent cache entries; defaulting to null instead of an empty array when no data exists.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/50c138ae7b3f3e89. Report an issue: GitHub.