206 Error Code | Stop Partial Content Loops Fast

A 206 Error Code is a partial-response delivery; check Range requests, caching, and server headers to stop repeat downloads.

Seeing a 206 status in logs can feel odd because the page may still load. The catch is that 206 isn’t an “error” in the classic sense. It’s a valid HTTP response used when a client asks for only part of a file. That’s normal for video, audio, PDFs, large downloads, resumable transfers, and many modern web apps.

The trouble starts when partial content shows up where you expected a full response, or when it repeats and burns bandwidth. This article shows what 206 is, when it’s fine, and how to track down the setups that turn it into slow pages, broken downloads, or stubborn cache misses.

What HTTP 206 Status Code Actually Indicates

HTTP status 206 is “Partial Content.” It happens when the request includes a Range header, such as Range: bytes=0-, and the server replies with only the requested byte range. The response usually includes Content-Range so the client can stitch the file together.

When everything is healthy, 206 is a performance tool. A player can fetch the next chunk of a video without re-downloading the whole file. A browser can resume a large download after a network drop. A download manager can split a file into parts for faster completion.

Most “problem 206” cases fall into two buckets:

  • Partial when full was expected — A script, proxy, cache rule, or client tool sends a Range request on a page or API endpoint that should return a complete response.
  • Partial on repeat — The same asset is requested again and again in ranges due to cache misses, inconsistent validators, or a player retry loop.

Common Triggers That Cause Unexpected Partial Content

Most confusing 206 patterns come from one of a few sources. The fastest path is to identify which layer is generating the Range request, then check what your server and cache do with it.

Symptom Likely Trigger First Place To Check
Static files show 206 in devtools Browser or extension sends Range Request headers in Network tab
CDN hits drop, origin traffic rises Cache bypass on ranged requests CDN policy for Range caching
Downloads fail to resume cleanly Incorrect Content-Range math Origin response headers and size
Video stalls at the same timestamp Origin blocks byte ranges Web server range settings
Service worker loops requests Fetch handler replays partial logic Service worker cache strategy

Range Headers From Browsers And Players

Browsers often request media in chunks. Many players also use byte ranges even for mid-sized files so they can seek quickly. If you run a site that serves audio, video, PDFs, or large downloads, 206 on those assets can be normal.

It turns into a headache when range requests hit HTML or JSON. That can happen when a client tool treats a dynamic URL like a resumable file download, or when a proxy rule injects Range headers more broadly than intended.

CDN And Reverse Proxy Behavior

Some CDNs treat Range requests as uncacheable unless you enable a setting for caching partial responses. Others can cache them, but only when the origin provides consistent cache headers. If your CDN bypasses cache for ranged requests, you’ll see origin spikes and slower starts for media.

Reverse proxies can also rewrite headers. A misconfigured rule can add or forward Range headers in a way that makes the origin serve chunks even when the client never asked for them.

Compression, Encoding, And Validator Drift

Byte ranges and compression can clash. If a cache stores a compressed version of a file, a later range request may not line up with the stored bytes. That mismatch can lead to extra requests, cache bypass, or playback issues.

Watch for Content-Encoding, Vary, and shifting ETag values. If those headers change between requests for the same URL, caches and clients may treat each response as a different object.

206 Error Code Fix Steps For Websites And APIs

If users report slow media starts, repeated downloads, or your logs show 206 on endpoints that should return full HTML or JSON, work through this sequence. Each step narrows the cause without guesswork.

  1. Confirm the request includes Range — Check server logs or devtools and look for the Range header on the request.
  2. Identify the request source — Compare user agents, device types, and paths to spot a single app, player, extension, or bot pattern.
  3. Validate Content-Range output — Make sure the origin returns a correct Content-Range with the right total length and byte boundaries.
  4. Check Accept-Ranges intent — For file assets, Accept-Ranges: bytes is normal. For endpoints that shouldn’t be ranged, aim for full responses.
  5. Review cache headers — Keep Cache-Control, ETag, and Last-Modified stable so caches don’t miss and re-fetch ranges.
  6. Test with and without compression — If encoding changes the byte stream, range behavior can degrade and retries can climb.
  7. Reproduce with curl — Run a ranged request and a full request to compare headers and payload sizes under controlled conditions.

Stop Range Requests On Dynamic Endpoints

APIs and HTML pages rarely benefit from byte ranges. If you see Range requests there, the core fix is to stop them at the source.

  • Check service worker fetch logic — If a service worker caches requests, confirm it does not add Range headers or replay partial responses for API calls.
  • Audit client libraries — Some download helpers treat any URL as resumable content. Use a dedicated download endpoint, not your JSON route.
  • Review proxy rewrite rules — Remove header rules that attach or forward Range headers for all paths.

If you can’t control the client, you can still enforce full responses on routes that should never be partial. Many servers will respond with 200 when range handling is disabled for a location, or when the resource isn’t suitable for byte ranges. Keep media routes separate so seeking still works where users expect it.

Fix Caching So Chunks Don’t Re-Download

When a player asks for ranges, you want the cache tier to serve those ranges without hitting the origin every time. Focus on consistency across requests.

  • Keep cache keys stable — Avoid surprise variation from query strings, device headers, or cookies for the same file.
  • Use strong validators — Stable ETag or Last-Modified values let caches and clients reuse content without refetching.
  • Align Vary usage — If you vary by encoding or language, keep that behavior consistent across every edge and origin response.

On some CDNs you’ll need to enable “cache range requests” (or an equivalent toggle). If it’s off, each range can bypass cache, turning one media view into many small origin fetches.

Correct Origin Range Handling For File Streams

Origins handle byte ranges at the web server layer or inside your app if you stream files through code. If range handling is wrong, you may see corrupted chunks, repeated retries, or stalled playback.

  • Stream from known byte offsets — If your app serves files, confirm it reads the correct offsets and sets headers that match the bytes sent.
  • Avoid double compression — If the app compresses output and the server also compresses, byte boundaries can shift and clients may retry ranges.
  • Verify upstream storage behavior — Object storage and gateways can enforce range limits; verify they return correct Content-Range values.

Browser And Device Checks That Explain “It Works For Me”

A 206 pattern can be device-specific. One person’s browser extension, privacy tool, or download manager may inject Range headers. Another user never triggers it. That mismatch can waste hours unless you test in a clean way.

  1. Try a clean browser profile — Disable extensions and test in a fresh profile to see if Range behavior changes.
  2. Compare private and normal windows — Some extensions are disabled in private mode, which can reveal header injection.
  3. Switch networks — A corporate proxy or ISP accelerator can rewrite headers; testing on mobile data can confirm it.
  4. Check download tools — Download accelerators split files into chunks; that creates multiple ranged requests by design.

If your audience uses smart TVs, set-top boxes, or in-car browsers, expect aggressive range usage. Those clients optimize for seeking and buffering, not for reducing request counts.

CDN, Load Balancer, And Cache Controls That Matter Most

If the origin is healthy but you see too many small requests, the cache tier is often the culprit. Tighten these areas first.

Cache Range Requests With Clear Rules

Look for a CDN setting that permits caching of partial responses. Pair it with stable caching directives on the asset so the CDN can reuse chunks reliably.

  • Set long caching for versioned assets — Fingerprinted files like app.4f2c.js can use long cache lifetimes because the name changes when content changes.
  • Use shorter caching for unversioned assets — If the URL stays the same while the file changes, keep lifetimes shorter and rely on validators.
  • Keep response headers consistent — If one edge sends different headers than another, clients may re-request ranges.

Watch For On-Edge Transform Side Effects

Some layers minify, recompress, or transform content automatically. That can alter the byte stream and break clean range math. Review settings like auto-minify, image transformation, and on-edge compression on routes that serve ranged assets.

If you transform content at the edge, keep the cached object consistent between requests. A file that changes shape between fetches will get re-fetched in pieces.

Keep Validators Consistent Across Backends

Multi-origin setups can produce mismatched validators if each backend generates them differently. If a load balancer sends two requests for the same URL to different backends with different ETag values, the client can’t reuse cached chunks reliably.

  • Standardize ETag behavior — Use a shared file store or deterministic ETag generation for static assets.
  • Route media to one source — Send large assets to a dedicated origin or storage bucket with consistent metadata.
  • Keep clocks aligned — Time skew can break If-Modified-Since flows and force refetches.

How To Monitor, Test, And Prevent Repeat 206 Patterns

Once you’ve fixed the cause, set up checks so the same issue doesn’t return. The goal is not to eliminate 206 everywhere. The goal is to keep partial content where it belongs and avoid it on endpoints that should be full responses.

Log The Right Fields

Add these fields to your logs for affected routes so patterns stand out fast.

  • Capture Range and Content-Range — Record request Range values and response Content-Range values for sampling.
  • Record cache status — Store CDN cache hit or miss markers so you can link 206 volume to cache bypass.
  • Track bytes sent — Repeat small ranges show up as high request counts with modest total bytes.

Run Repeatable Tests After Changes

Use a small test plan you can run after config edits or deploys.

  1. Request a full asset — Fetch with no Range header and confirm a 200 response with expected cache headers.
  2. Request a byte range — Fetch with a Range header and confirm 206 with correct Content-Range and consistent validators.
  3. Replay from cache — Repeat the same range request and confirm the CDN serves it without an origin fetch.

Know When Partial Content Is The Right Outcome

Teams sometimes chase 206 responses as if they’re failures. They aren’t. The real question is whether the partial response is intentional for that resource. For media, PDFs, and large downloads, byte ranges are normal. For dynamic HTML and most APIs, ranged fetching often points to a client tool or proxy behavior that needs cleanup.

If you’re stuck, start with a single request trace and follow it hop by hop. You’ll usually spot the first point where Range appears or where caching stops behaving like you expect.

After you stabilize the setup, keep one simple alert: a sudden rise of 206 error code responses on API routes, or a sudden drop in cache hits on ranged media. That gives you early warning before users report buffering, stalled downloads, or slow starts.

When you see a 206 error code again, treat it as a clue, not a verdict. Check the Range header, confirm caching behavior, and verify Content-Range math. Those three checks fix most repeat loops without burning a day.