gitroomhq/postiz-app · error · BadBody

The media storage did not return the requested byte range, p

Error message

The media storage did not return the requested byte range, please try again

What it means

The YouTube provider fetches a byte range of the stored video (Range: bytes=X-Y) for resumable chunked upload. It requires the storage to answer HTTP 206 Partial Content; any other status (200 full file, 403, 404, HTML error page) means the bytes written at the current offset would corrupt the upload, so it throws BadBody.

Source

Thrown at libraries/nestjs-libraries/src/integrations/social/youtube.provider.ts:480

    if (path.indexOf('http') === 0) {
      // identity encoding so the store keeps content-length and can answer
      // with the requested range: a transformed (compressed) response loses
      // its length, and a length-less object is answered with the full body.
      setHeartbeatDetails(
        `youtube: read media ${start}-${end} ${stripQuery(path)}`
      );
      const response = await fetch(path, {
        headers: {
          Range: `bytes=${start}-${end}`,
          'accept-encoding': 'identity',
        },
        dispatcher: getSsrfSafeDispatcher(),
      } as any);

      // A store that ignores Range (200 with the full file) or answers with an
      // error page would corrupt the upload at this offset.
      if (response.status !== 206) {
        throw new BadBody(
          this.identifier,
          '{}',
          '{}',
          'The media storage did not return the requested byte range, please try again'
        );
      }

      return response.body;
    }

    return createReadStream(path, { start, end });
  }

  // Asks the upload session for the truth: the created video when the upload
  // completed, or the exact byte offset to resume from. We use the global fetch
  // because the probe answers with 308 (Resume Incomplete), which this.fetch
  // would treat as an error.
  private async probeUploadSession(

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Check that the media URL supports range requests: curl -H 'Range: bytes=0-1023' -o /dev/null -w '%{http_code}' <url> should print 206
  2. Fix proxy/CDN config to forward Range headers and return 206
  3. Regenerate/re-upload the media so a fresh signed URL is used, then retry the post
  4. If storage cannot support ranges, upload smaller media that fits a single chunk or fix the storage backend

Example fix

// before
if (response.status !== 206) { throw new BadBody(...); }

// after (no library change needed; verify storage)
// curl -H 'Range: bytes=0-1023' -w '%{http_code}' https://media-url -> must be 206
const ok = response.status === 206;
if (!ok) { throw new BadBody(this.identifier, '{}', '{}', 'The media storage did not return the requested byte range, please try again'); }
Defensive patterns

Strategy: validation

Validate before calling

const r = await fetch(url, { headers: { Range: 'bytes=0-1023' } });
if (r.status !== 206) throw new Error('Storage does not honor Range requests');

Type guard

const supportsRange = async (url: string) => (await fetch(url, { headers: { Range: 'bytes=0-0' } })).status === 206;

Try / catch

catch (e) { if (/did not return the requested byte range/.test(e.message)) { await refreshMediaUrl(); retryPost(); } throw e; }

Prevention

When it happens

Trigger: Video upload chunking where the storage ignores Range requests and returns 200 with the entire file, or the signed URL expired/has wrong permissions and returns 4xx with an error body instead of the requested range.

Common situations: S3-compatible stores or proxies that don't support range requests; MinIO/nginx misconfiguration stripping Range headers; expired pre-signed media URLs; CDN caching a full-file 200 response.

Related errors


AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27). Data as JSON: /api/errors/06332fa409a0e1f5. Report an issue: GitHub.