Thanks again for working through this with me; I’ve had some time to focus to make sure I’m reading everything right again, and have run that.
I’m running curl -v -o NUL -r 0-1023 -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Tower/++UE4+Release-4.22-CL-0 UnrealEngine/4.22.3-0+++UE4+Release-4.22 Safari/537.36" -e "https://media-cache.towerunite.com/" https://my.domain.dev/path/to/file.webm
And get this output:
* Trying 172.67.154.158:443...
* Host my.domain.dev:443 was resolved.
* IPv6: 2606:4700:3035::ac43:9a9e, 2606:4700:3037::6815:620
* IPv4: 172.67.154.158, 104.21.6.32
* ALPN: curl offers h2,http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [1570 bytes data]
* SSL Trust Anchors:
* CAfile: /etc/ssl/certs/ca-certificates.crt
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [1210 bytes data]
* TLSv1.3 (IN), TLS change cipher, Change cipher spec (1):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [19 bytes data]
* TLSv1.3 (IN), TLS handshake, Unknown (25):
{ [2339 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [79 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / id-ecPublicKey
* ALPN: server accepted h2
* Server certificate:
* subject: CN=domain.dev
* start date: Aug 19 16:28:19 2026 GMT
* expire date: Nov 17 16:28:18 2026 GMT
* issuer: C=US; O=Let's Encrypt; CN=YE2
* Certificate level 0: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA384
* Certificate level 1: Public key type EC/secp384r1 (384/192 Bits/secBits), signed using ecdsa-with-SHA384
* Certificate level 2: Public key type EC/secp384r1 (384/192 Bits/secBits), signed using ecdsa-with-SHA384
* Certificate level 3: Public key type EC/secp384r1 (384/192 Bits/secBits), signed using ecdsa-with-SHA384
* subjectAltName: "my.domain.dev" matches cert's "*.domain.dev"
* OpenSSL verify result: 0
* SSL certificate verified via OpenSSL.
* Established connection to my.domain.dev (172.67.154.158 port 443) from [local IPv4 client address] port 60322
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 0* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://my.domain.dev/path/to/file.webm
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: my.domain.dev]
* [HTTP/2] [1] [:path: /path/to/file.webm]
* [HTTP/2] [1] [range: bytes=0-1023]
* [HTTP/2] [1] [user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Tower/++UE4+Release-4.22-CL-0 UnrealEngine/4.22.3-0+++UE4+Release-4.22 Safari/537.36]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [referer: https://media-cache.towerunite.com/]
} [5 bytes data]
> GET /path/to/file.webm HTTP/2
> Host: my.domain.dev
> Range: bytes=0-1023
> User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Tower/++UE4+Release-4.22-CL-0 UnrealEngine/4.22.3-0+++UE4+Release-4.22 Safari/537.36
> Accept: */*
> Referer: https://media-cache.towerunite.com/
>
* Request completely sent off
} [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [230 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [230 bytes data]
< HTTP/2 200
< date: Thu, 20 Aug 2026 17:11:03 GMT
< content-type: video/webm
< server: cloudflare
< last-modified: Wed, 11 Feb 2026 18:04:52 GMT
< vary: Accept-Encoding
< etag: <REDACTED>
< expires: Fri, 21 Aug 2026 17:11:03 GMT
< cache-control: max-age=86400
< x-content-type-options: nosniff
< report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=4DENcyNjmZCru1Ah2hhaxj6xk%2BYKv3y0P0fdxsbfLy5v%2Fyld%2BpGtD3UmOMPD88xoYFcjJ%2FZbtu%2Bm0aHzmXLxsp3MfVcHFuqH9hCe1IODO1r62NZmEticuIPd41uL2eCdkcg%3D"}]}
< cf-cache-status: DYNAMIC
< nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
< strict-transport-security: max-age=31536000; includeSubDomains; preload
< cf-ray: a2e303d488560ba1-ATL
< alt-svc: h3=":443"; ma=86400
<
{ [5 bytes data]
100 49.06M 0 49.06M 0 0 3.56M 0 00:13 3.58M
* Connection #0 to host my.domain.dev:443 left intact
I’ve only obfuscated my.domain.dev as a standin for my subdomain, and /path/to/file.webm as a standin for the actual path to my file. I was under the impression h.264/mp4 files would not work at all; as a result, all of my media is encoded with libvpx-vp9 video, libopus audio, and in webm containers.
I definitely don’t get a HTTP 206 Partial Content response, I get HTTP/2 200 instead. I don’t think this should be an issue; if it was, why would it still work using http://[IPv6]/path/to/file.webm in game, but just not https://my.domain.dev/path/to/file.webm, being one file complete with a 200, rather than a 206/207, partial response?
Likewise, I get video/webm instead of video/mp4, but given my files are webm instead, I don’t see a problem there.
I am not using nginx proxy manager for my.domain.dev - I quite using it for this purpose, thinking it might be part of the issue. I do call my ssl certificates out of the directory where I have them stored, under npm, but just as a filebrowser path; this nginx server stands on its own, and has its own AAAA record being updated, completely independently from the way I do most of my other web servers, running through nginx-proxy-manager.
Here’s my default.conf (only one I have, given this is all this entire nginx docker container is set up for);
# Need to see about adding these in to improve playback in game; not allowed here in this config apparently
#worker_processes auto;
#events {
# worker_connections 4096;
# use epoll;
# multi_accept on;
#}
map $scheme $hsts_header {
https "max-age=63072000;includeSubDomains; preload";
}
server {
listen 80;
listen 443 ssl;
listen [::]:80;
listen [::]:443 ssl;
server_name my.domain.dev;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_protocols TLSv1.3;
add_header Strict-Transport-Security $hsts_header always;
root /path/to/media/root;
# Set a list of index files to attempt to use.
#index index.html index.htm;
location / {
# First attempt to server files as direct files,
# then attempt to serve request as a directory,
# fail to a 404 if needed to avoid recursion redirects
try_files $uri $uri/ =404;
# Optimizations for video streaming
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
expires 1d;
gzip on;
gzip_types video/webm;
types {
video/webm webm;
}
add_header Accept-Ranges bytes;
# Fancy index settings:
# MAKE SURE FANCY INDEX IS ONLY ON WHEN WE NEED TO BE BROWSING THE INDEX!
fancyindex on;
fancyindex_directories_first on;
#fancyindex_name_length 255; # Maximum length of any given filename.
# Broken as of 9 July 2026? Won't stop [emerg] if this is uncommented!
fancyindex_localtime off; # on = use local time instead of GMT.
fancyindex_exact_size off; # on = output human-readable file sizes.
auth_basic "Authentication Required";
auth_basic_user_file /config/keys/.htpasswd;
# Explicitly deny security risks
location ~ /\.ht {deny all;} # .ht*, such as .htaccess or .htpasswd
# Implicit override in case we need to allow all file extensions for debugging.
# If we don't need this for debugging, this should be commented out.
# Don't ever set this to deny all, or it'll deny all access to literally everything lol
#location ~* \.\w+$ {allow all;}
# Specific file extensions we want denied or allowed.
location ~* ^.+\.(mkv|mp4|nfo)$ {
deny all;
}
location ~* ^.+\.(txt)$ {
allow all;
#try_files $uri =404;
types {
text/basic txt;
}
}
location ~* ^.+\.(webm)$ {
allow all;
auth_basic off;
}
}
}
Maybe it something to do with how I’ve configured the nginx server, but again, I hadn’t figured that, since the direct ipv6 address works, but the domain doesn’t. Hopefully this can shed a bit more light when you have time Nito - I’ve only obfuscated my domain, paths to files, and one instance of my local client IP address, just to be safe. All the other addresses in these logs are actually cloudflare’s, so I didn’t see any point to obfuscating them.
I just redacted one more thing, etag - not a clue what this is, or if there’s anything somebody could do with it, but you redacted it, so I’ve done the same. I do not see any content-range message, but maybe that’s because I’m pushing the entire file with my nginx config file? Same reason I get 200 instead of 206? Not sure if that’s part of the problem, or my lack of cf-mitigated; maybe the latter makes more of a difference, since the same AAAA address being written as the record for my.domain.dev at cloudflare works, but the domain, through cloudflare, doesn’t?
I’ve had a quick search for that cf-mitigated header, and maybe not? Seems like that should only be presented when cloudflare wants to challenge, and the response isn’t coming direct from the origin server, which makes me think its a good thing I don’t get that, but also curious why you expect it to happen, and how a lack of a cloudflare “are you human” challenge could be preventing it from working in-game, somehow 
Thinking on it, maybe what’s happen is cloudflare isn’t allowing the entire file through, because I’m trying to push the entire thing in one go, with the 200 response? With the AAAA, my origin server can send the files straight to the clients, but introducing the domain name, means it should be going through cloudflare; maybe its a rate-limit thing, and I actually do need to be not sending the entire file at once, and expecting a 206 response and that content-range header? Seems viable to me, at least - will have to see about what I’d need to change about my nginx config to do that…