docling-project/docling · error · ValueError

Unsupported numpy dtype for gRPC inline (non-binary) encodin

Error message

Unsupported numpy dtype for gRPC inline (non-binary) encoding: {tensor.dtype!s}. Supported non-binary dtypes: bool, uint8/uint16/uint32/uint64, int8/int16/int32/int64, float32/float64, BYTES.

What it means

Raised as ValueError by _encode_contents when building a non-binary (inline) KServe gRPC tensor from a numpy array whose dtype is not in the supported set (bool, u8-u64, i8-i64, f32/f64, object/BYTES). Notably float16 and bfloat16 are rejected.

Source

Thrown at docling/models/inference_engines/common/kserve_v2_grpc.py:131

    flat = tensor.flatten()
    if tensor.dtype == np.float32:
        contents.fp32_contents.extend(flat.tolist())
    elif tensor.dtype == np.float64:
        contents.fp64_contents.extend(flat.tolist())
    elif tensor.dtype in (np.int8, np.int16, np.int32):
        contents.int_contents.extend(flat.astype(np.int32).tolist())
    elif tensor.dtype == np.int64:
        contents.int64_contents.extend(flat.tolist())
    elif tensor.dtype in (np.uint8, np.uint16, np.uint32):
        contents.uint_contents.extend(flat.astype(np.uint32).tolist())
    elif tensor.dtype == np.uint64:
        contents.uint64_contents.extend(flat.tolist())
    elif tensor.dtype == np.bool_:
        contents.bool_contents.extend(flat.tolist())
    elif tensor.dtype == object:
        contents.bytes_contents.extend(encode_bytes_element(value) for value in flat)
    else:
        raise ValueError(
            f"Unsupported numpy dtype for gRPC inline (non-binary) encoding: {tensor.dtype!s}. "
            "Supported non-binary dtypes: bool, uint8/uint16/uint32/uint64, "
            "int8/int16/int32/int64, float32/float64, BYTES."
        )


def _decode_contents(
    contents: Any, np_dtype: np.dtype[Any], shape: tuple[int, ...]
) -> np.ndarray:
    """Decode an InferTensorContents message to a numpy array (non-binary path)."""
    canonical_dtype = np.dtype(np_dtype)

    if canonical_dtype == np.dtype(np.float32):
        data = list(contents.fp32_contents)
    elif canonical_dtype == np.dtype(np.float64):
        data = list(contents.fp64_contents)
    elif canonical_dtype in (
        np.dtype(np.int8),

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Cast to a supported dtype before the request: arr.astype(np.float32).
  2. For half-precision pipelines, cast at the boundary right before sending.
  3. If binary transport is enabled (use_binary_data=True), raw bytes are sent instead and the dtype restriction applies to the declared datatype string — but casting to fp32 is still the simplest fix.

Example fix

# before
payload = pixels.astype(np.float16)  # -> ValueError on encode

# after
payload = pixels.astype(np.float32)  # supported inline dtype
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
SUPPORTED = {np.bool_, np.uint8, np.uint16, np.uint32, np.uint64,
             np.int8, np.int16, np.int32, np.int64, np.float32, np.float64, np.dtype(object)}
if tensor.dtype not in SUPPORTED:
    tensor = tensor.astype(np.float32)

Type guard

import numpy as np

def is_supported_inline_dtype(arr: np.ndarray) -> bool:
    return arr.dtype in (np.bool_, np.uint8, np.uint16, np.uint32, np.uint64,
                         np.int8, np.int16, np.int32, np.int64,
                         np.float32, np.float64) or arr.dtype == object

Prevention

When it happens

Trigger: Sending a np.float16 image tensor, a float128, a datetime64, or a structured dtype through the inline tensor-contents path of the gRPC client.

Common situations: Half-precision preprocessing pipelines (fp16 common on GPUs); mixed-precision exports; object arrays containing non-bytes elements hitting the BYTES branch expectations.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/a206ea5a348a948e. Report an issue: GitHub.