Comfy-Org/ComfyUI · error · ValueError
File3DToSplat: .splat size is not a multiple of 32 bytes
Error message
File3DToSplat: .splat size is not a multiple of 32 bytes
What it means
Raised by _parse_splat_gaussian when parsing antimatter15-format .splat data whose byte length is not a multiple of 32. Each splat is a fixed 32-byte record (3 f32 position + 3 f32 scale + 4 u8 RGBA + 4 u8 quantized quaternion), so any remainder indicates a truncated, corrupted, or non-.splat file.
Source
Thrown at comfy_extras/nodes_gaussian_splat.py:269
rest = sorted((k for k in names if k.startswith('f_rest_')), key=lambda s: int(s.split('_')[-1]))
if rest:
r = np.stack([c(k) for k in rest], 1) # (N, 3*(K-1)) channel-major
kk = r.shape[1] // 3 + 1
r = r.reshape(n, 3, kk - 1).transpose(0, 2, 1) # -> (N, K-1, 3)
sh = np.concatenate([dc[:, None, :], r], 1)
else:
sh = dc[:, None, :]
elif 'red' in names:
sh = _rgb_to_sh_dc(np.stack([c('red'), c('green'), c('blue')], 1) / 255.0)
else:
sh = np.zeros((n, 1, 3), np.float32)
return xyz, scale, rot, opacity, sh
def _parse_splat_gaussian(data: bytes):
# antimatter15 .splat: 32-byte records (f32 xyz, f32 scale, u8 rgba, u8 quat as (b-128)/128 wxyz).
if len(data) % 32 != 0:
raise ValueError("File3DToSplat: .splat size is not a multiple of 32 bytes")
rec = np.frombuffer(data, np.dtype([('xyz', '<f4', 3), ('scale', '<f4', 3),
('rgba', 'u1', 4), ('quat', 'u1', 4)]))
rgba = rec['rgba'].astype(np.float32) / 255.0
rot = _norm_quat((rec['quat'].astype(np.float32) - 128.0) / 128.0) # wxyz
return (rec['xyz'].astype(np.float32), rec['scale'].astype(np.float32), rot,
rgba[:, 3].copy(), _rgb_to_sh_dc(rgba[:, :3]))
def _parse_ksplat_gaussian(data: bytes):
# mkkellogg SplatBuffer: 4096-byte header, N section headers, then per-section splat data. Supports
# levels 0 (float) / 1 (half + bucketed positions) / 2 (half, uint8 SH). SH is skipped (base color kept).
if data[0] != 0:
raise ValueError(f"File3DToSplat: unsupported .ksplat version {data[0]}.{data[1]}")
max_sections = struct.unpack_from('<I', data, 4)[0]
level = struct.unpack_from('<H', data, 20)[0]
if level not in _KSPLAT_COMPRESSION:
raise ValueError(f"File3DToSplat: invalid .ksplat compression level {level}")
bc, bs, br, bcol, bshc, default_range = _KSPLAT_COMPRESSION[level]View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Verify the file size: size % 32 must be 0 and match the expected splat count times 32.
- Re-download or regenerate the .splat from its source.
- Confirm the file is actually antimatter15 .splat format, not another splat flavor renamed to .splat.
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
data = open(path, 'rb').read()
if data[:3] == b'ply' or data[:2] == b'\x1f\x8b' or (len(data) >= 2 and data[0] == 0 and data[1] >= 1):
pass # other formats
elif len(data) % 32 != 0:
raise ValueError(f'{path} is not a valid 32-byte-record .splat (size {len(data)})') Type guard
def is_splat_v1(data: bytes) -> bool:
return (len(data) > 0 and len(data) % 32 == 0
and data[:3] != b'ply' and data[:2] != b'\x1f\x8b') Try / catch
try:
result = _parse_splat_gaussian(data)
except ValueError as e:
if 'multiple of 32 bytes' in str(e):
re_fetch_or_reconvert(path)
else:
raise Prevention
- Check size % 32 == 0 before treating a file as antimatter15 .splat.
- Verify downloads by size against the source.
When it happens
Trigger: File3DToSplat on data that failed the ply/spz/ksplat signature checks but whose length happens not to divide by 32 — typically a genuinely truncated or corrupted .splat, or an arbitrary binary file with an unlucky length. Also a partially uploaded/downloaded .splat.
Common situations: Truncated download of a .splat; file cut off mid-write; feeding a random binary blob to the node hoping it is a splat.
Related errors
- SplatToFile3D: gaussian is empty
- File3DToSplat: not a PLY (missing end_header)
- File3DToSplat: invalid .spz (bad magic)
- INVALID_TAG_FILTER
- UNSUPPORTED_MEDIA_TYPE
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/ad2e366a6567d0c2.
Report an issue: GitHub.