For now, I couldn’t reproduce this directly since I don’t have access to an Apple environment, but:
@rajatarya
I don’t think the Range value you captured is invalid in the normal HTTP sense.
For a 3,551,137-byte representation,
Range: bytes=0-3551136
is exactly the whole representation: byte offsets are zero-based and the last position is inclusive. RFC 9110 §14.1.2 also says that if last-pos is at or beyond the current representation length, the range is interpreted as the remainder of the representation. So even a one-past-end last position would not, by itself, make an otherwise satisfiable range invalid.
That makes this part of the response especially interesting:
HTTP 403
Auth failed: invalid range
because it does not look like ordinary HTTP “requested byte range is unsatisfiable” handling. HTTP has 416 Range Not Satisfiable for that class of problem.
I also ran a small server-side control against the same public Joint1_v2.mp4. I could not reproduce Safari itself, but I could test the Hub → Xet bridge → CDN path and vary the Range request independently.
The result was useful: from my Colab/Linux environment, Hugging Face routed the file to us.gcp.cdn.hf.co, and the same closed full-file range that failed for you through us.aws.cdn.hf.co worked normally:
Your Safari embedded request:
us.aws.cdn.hf.co
Range: bytes=0-3551136
→ 403 Auth failed: invalid range
My server-side control:
us.gcp.cdn.hf.co
Range: bytes=0-3551136
→ 206 Partial Content
I also tried the visible media-request headers from your capture (Accept-Encoding: identity, Sec-Fetch-Dest: video, Sec-Fetch-Mode: no-cors, Sec-Fetch-Site: cross-site, and the HF Referer), and that still returned 206.
So at this point I would move “Safari generated an intrinsically invalid Range” fairly far down the list.
The most informative distinction now looks like:
Do the failing Safari path and the two successful paths actually reach the same CDN host / POP, and do they send the same sequence of Range requests?
HF’s current download documentation explicitly lists both us.aws.cdn.hf.co and us.gcp.cdn.hf.co as CDN endpoints, so the AWS/GCP difference is a real delivery-path distinction rather than just cosmetic hostname variation.
The first comparison I would make
You already have three very good controls:
| Path |
Result |
Safari + embedded <video> |
fails |
| Safari + direct MP4 |
works |
Firefox + embedded <video> |
works |
For those three, the highest-value fields seem to be:
final CDN hostname
x-hf-cdn-pop (if present)
HTTP version
Range requests immediately before the failure
status
Content-Range
Content-Length
Accept-Ranges
And, if they are readily visible:
X-Cache
Via
ETag
Last-Modified
If-Range
request / trace IDs
In particular, I would look at the sequence, not only the final failing request. Safari/WebKit media loading is known to use small byte-range probes such as bytes=0-1; WebKit developers have explicitly noted that such a request is not inherently incorrect and that a range-capable server should normally answer it with 206. See WebKit bug 284443.
So, for example, this would be a very informative trace:
bytes=0-1 → 206
bytes=0-3551136 → 403
because it would point much more specifically at handling of the second request than at video decoding or Safari’s use of Range requests in general.
Why I think the reported Range itself is OK
The byte-range rules are fairly unambiguous here.
From RFC 9110 §14.1.2:
- byte offsets start at zero;
last-pos is inclusive;
- an integer range is satisfiable when
first-pos is less than the current representation length;
- if
last-pos is omitted or is greater than or equal to the representation length, it is interpreted as the remainder of the representation.
For a length of:
3,551,137 bytes
the final byte is therefore:
3,551,136
and this is an exact full-file closed range:
bytes=0-3551136
There is also an important distinction between an HTTP-invalid range expression and an unsatisfiable range.
For example:
bytes=100-50
is invalid because the last position is below the first.
But a syntactically valid range whose first byte is already beyond the representation is normally an unsatisfiable range. HTTP defines 416 Range Not Satisfiable for that case, and a byte-range 416 response should normally include something like:
Content-Range: bytes */3551137
That distinction also showed up cleanly in my control test: when I deliberately requested the first byte after the file,
Range: bytes=3551137-3551137
the CDN returned 416.
So the observed:
403
Auth failed: invalid range
looks like a different failure class — perhaps an authorization, validation, bridge, or edge-layer check involving the Range — rather than straightforward RFC byte-range satisfiability.
I would still avoid calling that an HF/CDN bug with certainty from outside the service, because an internal validator could be checking something other than the public object’s apparent byte length.
What I could and could not reproduce without Safari
I used the same public Joint1_v2.mp4, obtained a fresh Hub resolve redirect, then reused the same final signed CDN URL while changing only the Range/header shape.
The route selected for my environment was:
huggingface.co/resolve/...
↓
us.gcp.cdn.hf.co/xet-bridge-us/...
The target tests were:
| Request |
Result |
no Range |
200 |
bytes=0- |
206 |
bytes=0-1 |
206 |
bytes=0-3551136 |
206 |
bytes=0-3551137 |
206 |
bytes=3551136-3551136 |
206 |
bytes=3551137-3551137 |
416 |
That bytes=0-3551137 result is also consistent with RFC 9110: when the end exceeds the representation length but the first position is valid, the server can simply return through the actual final byte.
I then used another fresh signed URL and sent:
bytes=0-1
followed by:
bytes=0-3551136
using the visible media-related headers from your Safari capture.
That produced:
206
206
I also did small 0-1 / 0- controls against sibling LeRobot MP4s, and those succeeded as well.
So this is a negative control, not a Safari reproduction:
- it shows the exact full-file closed range can work through the Xet bridge/CDN path;
- it makes a universal
xet-bridge rejection of 0-(size-1) less likely;
- it does not prove that Safari is doing nothing different;
- and it does not prove that GCP and AWS edges are configured identically.
In fact, the different CDN route is probably the most interesting thing that fell out of the test.
Why I would separate the Xet bridge path from native Xet downloads
One terminology/detail that may help future debugging:
the browser path here should not automatically be treated as the native Xet download protocol used by hf_xet.
HF’s current Backward Compatibility with LFS documentation says that non-Xet-aware clients are supported through a Git LFS bridge. A native Xet-aware client receives reconstruction information from CAS, whereas a legacy/web client can receive a single URL through the bridge.
The Xet file-ID documentation makes the same distinction when following a normal Hub resolve redirect.
That matters because native Xet has its own range-oriented mechanisms and signed download protocol, but I don’t think it is safe to take those internal/native-Xet rules and assume they directly explain what an HTML <video> request to:
.../xet-bridge-us/...
is doing.
For this case, I would describe the boundary more conservatively as something like:
Safari media loader
↓
Hub resolve redirect
↓
legacy / HTTP-compatible Xet bridge path
↓
selected CDN / edge
and try to identify which boundary first differs between the successful and unsuccessful cases.
A nearby Xet/CDN precedent — similar failure shape, not necessarily the same bug
Your link to xet-core#897 still looks relevant to me, but mainly as a failure-domain precedent, not as evidence of the same root cause.
That issue reported a different error:
403
Auth failed: SignatureError: invalid key pair id
and involved the GCP CDN rather than the AWS CDN.
The useful part of that report is the control structure.
For the same requested data/range:
transfer.xethub.hf.co → 206
us.gcp.cdn.hf.co → 403
and the selected fetch hosts differed depending on the client’s network/egress environment.
It also reported that switching away from the native Xet client did not necessarily avoid the failure, because the compatibility/bridge path could still be redirected to the affected CDN.
So I would not infer:
#897 == this Safari problem
but it does show that:
“same underlying HF/Xet-backed data, but one selected delivery endpoint accepts the request and another rejects it”
is a failure shape that has occurred before.
That is why I think comparing the final host/POP for Safari embedded, Safari direct, and Firefox embedded is probably higher-value now than changing the MP4 itself.
As of this reply, #897 is closed, although I do not see a public fix explanation there that would justify assuming the present issue is the same resolved problem.
Another useful HF Range precedent, but again a different bug
There is also a fairly detailed 2026 investigation in huggingface_hub PR #3778.
That was not this failure either.
In that case, a resumed HTTP download sent a Range request, but CloudFront returned 200 with the whole gzip-compressed object rather than 206, and the client appended it to already-downloaded data.
What makes the investigation useful here is the method: the HF-side debugging correlated the Range-bearing requests with a specific edge POP and the actual CDN request logs.
So fields such as:
x-hf-cdn-pop
request ID
final host
Range
status
could be particularly useful if somebody with access to the CDN/bridge logs looks at this later.
That PR also gives us a useful negative comparison. Your Safari request explicitly has:
Accept-Encoding: identity
whereas the #3778 failure involved Range behavior in combination with gzip encoding. So I would not currently merge that old bug with this one.
A small timing / infrastructure note
There is one current operational detail worth recording, although I would treat it as correlation only.
The Hugging Face status page shows an AWS CDN (Singapore) incident on August 7, 2026, which was resolved at 23:14 UTC. The status update says downloads from that region were stable after the fix and that additional capacity was added.
At the time I checked, both the AWS CDN and Google Cloud CDN are reported Operational.
This does not establish a connection to this report:
- that incident was an elevated-error/download incident, not specifically this
403 Auth failed: invalid range;
- we do not yet know which AWS POP served your failing request;
- and the problem may reproduce outside that incident window.
Still, if the failing response happens to include an AWS Singapore/APAC POP identifier, the exact request time and POP would be useful context to preserve.
If it points to a completely different region, I would mostly ignore this incident and continue with the browser/CDN comparison above.
A compact decision tree
I would currently split it this way:
Safari embedded fails
│
├─ Do Safari embedded, Safari direct, and Firefox embedded
│ reach the same final CDN host / POP?
│
├─ NO
│ │
│ └─ CDN routing / edge / signing / configuration difference
│ becomes much more interesting.
│
└─ YES
│
├─ Do they send different Range sequences?
│
├─ YES
│ │
│ └─ Compare those Range shapes using the same fresh signed URL.
│ │
│ ├─ Only bytes=0-(N-1) fails
│ │ └─ closed-full-range handling becomes very interesting.
│ │
│ ├─ Every Range request fails but no-Range works
│ │ └─ general Range/auth handling on that route becomes interesting.
│ │
│ └─ All curl controls succeed
│ └─ browser request chronology / connection state /
│ protocol / hidden header differences become more likely.
│
└─ NO, essentially the same Range too
│
├─ Same host but different POP / edge IDs
│ └─ edge/configuration difference remains plausible.
│
└─ Same host + same POP + same Range,
Firefox works and Safari fails
└─ Safari/media-loader-specific request context becomes
substantially stronger.
There is another useful branch if any response exposes a surprising representation length:
Content-Range: bytes .../<unexpected size>
If the CDN/bridge believes the object has a different length from 3,551,137 bytes, then a stale or mismatched representation/object metadata path would deserve a much higher ranking.
At the moment I would keep that below the CDN/request-path hypotheses because the same Joint1_v2.mp4 works normally through the GCP bridge route in my control.
Things I would not change yet
I would personally postpone these as fixes:
- re-encoding the MP4;
- changing codec;
- adding
faststart;
- changing MIME handling;
- replacing the
<video> element with JavaScript fetching;
- assuming CORS is the root cause.
MP4 layout can absolutely affect which ranges a media engine chooses to request, so it can matter indirectly.
But in the captured failure, the request reaches the CDN and receives:
403
Auth failed: invalid range
before media decoding becomes the interesting part.
And the same MP4 can be opened directly in Safari, which is already a useful control against a simple “Safari cannot decode this file” explanation.
Similarly, Sec-Fetch-Mode: no-cors on a media fetch is not automatically suspicious. Native media fetching and JavaScript fetch() also do not have exactly the same security/request behavior, so replacing one with the other too early could change the experiment rather than isolate the original failure.
I would first preserve the failing case and compare its network path.
If a same-signed-URL test becomes useful
If the successful and failing browser captures still leave ambiguity, a very small curl matrix against one fresh final signed URL can separate several possibilities without needing to reproduce Safari:
# Conceptually:
GET with no Range
Range: bytes=0-
Range: bytes=0-1
Range: bytes=0-3551136
Using exactly the same final signed URL matters: otherwise URL generation/routing differences get mixed into the Range comparison.
If useful, an intentionally unsatisfiable control is:
Range: bytes=3551137-3551137
for this 3,551,137-byte object.
Expected interpretation would be roughly:
| Observation |
What it would favor |
0- succeeds, exact 0-(N-1) gets the 403 |
closed full-range validation edge case |
| all Range forms get 403, no-Range succeeds |
general Range/auth interaction |
| all forms return 206/200 normally |
something specific to browser path/sequence/edge |
| truly out-of-range request gets normal 416 while Safari range gets 403 |
separate HTTP range-vs-auth failure classes |
| behavior changes across CDN hosts/POPs |
routing / edge configuration |
One practical caution: I would avoid posting the full signed CDN URL publicly. The hostname, sanitized path shape, relevant headers, POP/request IDs, status and response body should normally carry the useful debugging information without publishing the temporary signature.
Also, use a freshly generated URL for this sort of comparison so URL expiration is not introduced as another variable.
So my current ranking would be approximately:
- an interaction between Safari’s media request pattern and the particular AWS CDN/bridge path it reaches;
- a CDN/POP/routing-specific validation or authorization difference;
- some less-visible Safari request-context difference that the simple curl reproduction did not copy;
- representation/metadata mismatch on one path;
- much lower: generic CORS, codec, MP4-format, or simple off-by-one explanations.
The key negative result for me is that the exact reported range is accepted as a normal 206 when the same Xet-backed object is delivered through the GCP CDN, while an actually unsatisfiable control gets the expected 416.
So if the Web Inspector screenshots are easy to capture, I think the most reusable ones would be the successful and failing requests side-by-side, including the request immediately before the failure and the final hostname / x-hf-cdn-pop / Range / response headers. That should tell us whether the next branch is primarily browser behavior or delivery-path behavior, without needing to guess at the internal root cause first.