Comfy-Org/ComfyUI · error · ValueError
File3DToSplat: invalid .spz (bad magic)
Error message
File3DToSplat: invalid .spz (bad magic)
What it means
Raised by _parse_spz_gaussian when the gzip-decompressed payload does not start with the expected .spz magic constant. _detect_splat_format routes any gzip file (\x1f\x8b) to the spz parser, so this error means the file is gzip but not an .spz once decompressed. Effectively a corrupted .spz or a different gzipped format.
Source
Thrown at comfy_extras/nodes_gaussian_splat.py:341
nf = min(full_splats, cnt)
idx[:nf] = np.arange(nf) // bucket_size
if cnt > full_splats:
lengths = np.frombuffer(data, '<u4', count=partial_buckets, offset=base)
idx[full_splats:] = np.repeat(full_buckets + np.arange(partial_buckets), lengths)[:cnt - full_splats]
xyz = (rec['center'].astype(np.float32) - scale_range) * (block_size / 2.0 / scale_range) + buckets[idx]
parts.append((xyz, scale, rot, colf[:, 3].copy(), _rgb_to_sh_dc(colf[:, :3])))
base += bytes_per_splat * sec_max + buckets_store
if not parts:
raise ValueError("File3DToSplat: .ksplat has no splats")
return tuple(np.concatenate([p[i] for p in parts]) for i in range(5))
def _parse_spz_gaussian(data: bytes):
# Niantic .spz (gzip-wrapped), versions 1-3. Base color only (SH skipped). See spark's SpzReader.
raw = gzip.decompress(data)
if struct.unpack_from('<I', raw, 0)[0] != _SPZ_MAGIC:
raise ValueError("File3DToSplat: invalid .spz (bad magic)")
version = struct.unpack_from('<I', raw, 4)[0]
n = struct.unpack_from('<I', raw, 8)[0]
frac_bits = raw[13]
off = 16
if version == 1:
xyz = np.frombuffer(raw, '<f2', count=n * 3, offset=off).astype(np.float32).reshape(n, 3)
off += n * 6
elif version in (2, 3):
b = np.frombuffer(raw, np.uint8, count=n * 9, offset=off).reshape(n, 3, 3).astype(np.int64)
v = (b[..., 2] << 16) | (b[..., 1] << 8) | b[..., 0]
v = np.where(v & 0x800000, v - 0x1000000, v) # sign-extend 24-bit
xyz = (v / (1 << frac_bits)).astype(np.float32)
off += n * 9
else:
raise ValueError(f"File3DToSplat: unsupported .spz version {version}")
alpha = np.frombuffer(raw, np.uint8, count=n, offset=off).astype(np.float32) / 255.0View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Confirm the file is a genuine Niantic-format .spz (e.g., open it in a viewer that supports spz).
- If it is another gzipped format, gunzip it first and load the inner format directly.
- Re-download the .spz if corruption is suspected.
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
import gzip, struct
data = open(path, 'rb').read()
if data[:2] == b'\x1f\x8b':
raw = gzip.decompress(data)
if struct.unpack_from('<I', raw, 0)[0] != 0x5053474e: # _SPZ_MAGIC value per repo
raise ValueError(f'{path} is gzip but not spz') Type guard
def is_spz(data: bytes) -> bool:
if data[:2] != b'\x1f\x8b':
return False
try:
raw = gzip.decompress(data)
except OSError:
return False
return len(raw) >= 4 and struct.unpack_from('<I', raw, 0)[0] == _SPZ_MAGIC Try / catch
try:
result = _parse_spz_gaussian(data)
except ValueError as e:
if 'bad magic' in str(e):
gunzip_and_inspect(path) # probably another gzipped format
else:
raise Prevention
- Do not feed arbitrary .gz files; the detector maps every gzip stream to the spz parser.
- Keep spz assets from trusted exporters and verify they open in an spz viewer.
When it happens
Trigger: File3DToSplat on a random .gz / gzipped non-spz file (any gzip stream matches the detection heuristic), or an .spz whose decompressed header is corrupted so the magic integer mismatches.
Common situations: Feeding a .gz archive or gzipped PLY to the node; a partially corrupted .spz transfer; renaming other files to .spz.
Related errors
- File3DToSplat: not a PLY (missing end_header)
- File3DToSplat: unsupported .spz version {version}
- File3DToSplat: unsupported PLY format '{p[1]}' (need binary_
- File3DToSplat: PLY vertex has list properties (unsupported)
- File3DToSplat: .splat size is not a multiple of 32 bytes
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/e69c41f2a6e21018.
Report an issue: GitHub.