sgl-project/sglang · error · ValueError

Could not decode audio: {e}

Error message

Could not decode audio: {e}

What it means

libsndfile (via soundfile sf.read) failed to decode the audio source — the bytes/path were passed to the decoder but it could not parse the container or codec. The ValueError wraps LibsndfileError so callers get a uniform failure regardless of file vs bytes input.

Source

Thrown at python/sglang/srt/utils/common.py:1760

        except Exception as e:
            # torchcodec's bytes-buffer IO can fail on WAV files that carry
            # large trailing metadata chunks. Fall back to soundfile, which reads the PCM payload directly.
            logger.warning(
                f"torchcodec AudioDecoder failed ({e}); falling back to soundfile + torchaudio."
            )

    # Fallback: soundfile + torchaudio (ARM / no FFmpeg / torchcodec failure)
    import soundfile as sf
    import torch
    import torchaudio

    try:
        if isinstance(source, bytes):
            audio, original_sr = sf.read(BytesIO(source))
        else:
            audio, original_sr = sf.read(source)
    except sf.LibsndfileError as e:
        raise ValueError(f"Could not decode audio: {e}") from e

    if mono and len(audio.shape) > 1:
        audio = np.mean(audio, axis=1)

    if original_sr != sr:
        audio_tensor = torch.from_numpy(audio).float()
        if audio_tensor.dim() == 1:
            audio_tensor = audio_tensor.unsqueeze(0)
        else:
            audio_tensor = audio_tensor.T
        audio_tensor = torchaudio.functional.resample(
            audio_tensor, orig_freq=original_sr, new_freq=sr
        )
        if audio_tensor.shape[0] == 1:
            audio = audio_tensor.squeeze(0).numpy()
        else:
            audio = audio_tensor.T.numpy()

View on GitHub (pinned to 0132848349)

Solutions

  1. Re-encode to WAV or FLAC (ffmpeg -i in.mp3 out.wav) before sending
  2. Ensure downloads complete (raise media timeout / size limits) and the source file is not corrupt
  3. Route MP4/M4A through the torchcodec/container decode path instead of sf.read (see is_audio_container/decode_audio_container)

Example fix

# before
wav, sr = load_audio('note.aac')  # libsndfile can't decode -> ValueError
# after (pre-convert)
# ffmpeg -i note.aac note.wav
wav, sr = load_audio('note.wav')
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-verify container is libsndfile-readable when format is uncertain
import soundfile as sf
if isinstance(source, bytes):
    sf.info(io.BytesIO(source))  # raises early with a clearer error

Try / catch

try:
    wav, sr = load_audio(path, sr=16000)
except ValueError as e:
    if 'Could not decode audio' in str(e):
        return HTTPException(400, f'unsupported/corrupt audio: {e}')
    raise

Prevention

When it happens

Trigger: Passing an audio file in a format libsndfile does not support (e.g. raw AAC/ADTS, some MP4/M4A streams, or corrupt/truncated files) to load_audio; download truncated by timeout so bytes are incomplete; note some formats are routed to decode_audio_container earlier, so this path means that routing did not apply.

Common situations: User uploads voice-note .m4a/.aac that libsndfile can't handle; truncated downloads; 0-byte files; mislabeled extensions (mp3 content in .wav path usually works, but exotic codecs don't).

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/b72888f257fece01. Report an issue: GitHub.