DrKLO/Telegram · warning
opus_custom_encode() failed: %s\n
Error message
opus_custom_encode() failed: %s\n
What it means
opus_custom_encode(enc, in, frame_size, data, bytes_per_packet) returned len <= 0 during the encoding loop. The message prints opus_strerror(len). Critically, this is a WARNING only — the code prints the error but does NOT break the loop or skip the subsequent decode, so it feeds a garbage/zero len to the decoder on failure.
Source
Thrown at TMessagesProj/jni/opus/celt/opus_custom_demo.c:139
if (argc>7)
{
complexity=atoi(argv[5]);
opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity));
}
in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));
out = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));
while (!feof(fin))
{
int ret;
err = fread(in, sizeof(short), frame_size*channels, fin);
if (feof(fin))
break;
len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet);
if (len <= 0)
fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len));
/* This is for simulating bit errors */
#if 0
int errors = 0;
int eid = 0;
/* This simulates random bit error */
for (i=0;i<len*8;i++)
{
if (rand()%atoi(argv[8])==0)
{
if (i<64)
{
errors++;
eid = i;
}
data[i/8] ^= 1<<(7-(i%8));
}
}View on GitHub (pinned to 45ab8f4308)
Solutions
- Check fread's return count and break/skip the iteration if it's less than frame_size*channels (partial frame).
- On len <= 0, skip the decode step (continue) instead of feeding the bad length to the decoder.
- Validate frame_size is an allowed CELT size for the chosen mode/rate before the loop.
- Read opus_strerror(len) to distinguish OPUS_BAD_ARG from OPUS_BUFFER_TOO_SMALL.
Example fix
// before
len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet);
if (len <= 0)
fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len));
// after: skip the rest of the loop body on encode failure
len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet);
if (len <= 0) {
fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len));
continue;
} Defensive patterns
Strategy: validation
Validate before calling
// Skip frames where the read was short or encode failed.
err = fread(in, sizeof(short), frame_size*channels, fin);
if (err != (size_t)(frame_size*channels)) { /* short read: end of data */ break; }
len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet);
if (len <= 0) { fprintf(stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len)); continue; } Prevention
- Check fread's count and skip partial frames rather than feeding them to the encoder.
- On len <= 0, continue the loop so decode isn't called with a bad length.
- Validate frame_size is an allowed CELT size before the loop.
When it happens
Trigger: The encoder returns a negative OPUS_* error code (e.g. OPUS_BAD_ARG if frame_size is invalid for the mode, OPUS_INTERNAL_ERROR) or 0. The input buffer 'in' is filled by fread each iteration; an incomplete final read (short frame) can also feed bad data.
Common situations: frame_size not a valid CELT frame size for the mode; input PCM shorter than a full frame on the last iteration (fread returns fewer samples but the code only checks feof after the read); bytes_per_packet of 0 forcing zero-length output; corrupted input samples.
Related errors
- Failed to create the encoder: %s\n
- opus_custom_decode() failed: %s\n
- failed to create a mode\n
- Failed to create the decoder: %s\n
- Error: encoder doesn't match decoder\n
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/19e4e2b9f4a4fefb.
Report an issue: GitHub.