HTTP 103 Early Hints: How to diagnose if they are correctly set by Cloudflare and respected by Chrome?

For my cryptocurrency market data website

Link: </fonts3.css>; rel="preconnect", </_app/assets/start-6f5e0715.css>; rel="preconnect", </_app/assets/pages/__layout.svelte-f31b19cc.css>; rel="preconnect", </_app/assets/pages/index.svelte-84a34be8.css>; rel="preconnect"

Now, how do I verify that

  • Cloudflare is correctly generating HTTP/1.1 103 Early Hints. Can I display this information with curl or wget?

  • Chrome is respecting the early hint - where this is shown in the Performance tab of webr developer tools, or somewhere else?

You can check my own tool here: https://code103.hotmann.de

try it several times, if it once tells you it could confirm the 103 Headers you can be sure it works. Please also notice the unique behaviour of Cloudflare in that case: Early Hints | Need More Data Before Switching Over - #21 by LucasCF

Please run it severare times to make sure it works, or does not work.

This does not answer the question at all, just connects ot to another question which searches for the same result.

To verrify yourself please run:

curl -X HEAD -I https://your.website.com

If it works, you will see a section at the top which states “HTTP/2 103” and then your link headers.

2 Likes

Thank you so much for the super responsive reply @M4rt1n.

Something seems to be off, because I am not getting HTTP/2 from Cloudflare at all.

curl --http2 -X HEAD -I https://tradingstrategy.ai
HTTP/1.1 200 OK
Date: Fri, 14 Jan 2022 11:50:08 GMT
Content-Type: text/html
Connection: keep-alive
Cache-Control: public, max-age=300
Link: </fonts3.css>; rel="preconnect", </_app/assets/start-6f5e0715.css>; rel="preconnect", </_app/assets/pages/__layout.svelte-f31b19cc.css>; rel="preconnect", </_app/assets/pages/index.svelte-84a34be8.css>; rel="preconnect"
Permissions-Policy: interest-cohort=()
Vary: Accept-Encoding
CF-Cache-Status: DYNAMIC
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=6u9WaaTENr8QYj6KnIyyeC7QrxQj4988DxWlcVk%2BwhKXyC3gQPpIErGAxEnuh9FL4iD2O3Djpm5IyY%2Fybvzzo6N9h4RDuJs%2FLOTvubH46NJXPOjJE6dq5vJy%2FG93KnBBRFvk3Q%3D%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Server: cloudflare
CF-RAY: 6cd6a51d8fd8666c-MAD
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400
1 Like

All good in the settings

(Continuing the post because of stupid forum post limitation rules)

1 Like

You are welcome!

Thats truly a problem since Early hints (#103) are just available for HTTP/2 and up.

But your command does differ from what I have sent you. Please use:

curl -X HEAD -I https://tradingstrategy.ai

For me it outputs:

$ curl -X HEAD -I https://tradingstrategy.ai
HTTP/2 103
link: </fonts3.css>; rel=preconnect, </_app/assets/start-6f5e0715.css>; rel=preconnect, </_app/assets/pages/__layout.sve
lte-f31b19cc.css>; rel=preconnect, </_app/assets/pages/index.svelte-84a34be8.css>; rel=preconnect

HTTP/2 200
date: Fri, 14 Jan 2022 11:53:12 GMT
content-type: text/html
cache-control: public, max-age=300
link: </fonts3.css>; rel="preconnect", </_app/assets/start-6f5e0715.css>; rel="preconnect", </_app/assets/pages/__layout
.svelte-f31b19cc.css>; rel="preconnect", </_app/assets/pages/index.svelte-84a34be8.css>; rel="preconnect"
permissions-policy: interest-cohort=()
vary: Accept-Encoding
cf-cache-status: DYNAMIC
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=sRztVL6vt6iOxXlvqKK8r7wlAoT94gvROC1wMWHijN
vTEFp1XjxTE0vZinxIBoKsnuPvH6dHvl3d5L%2FRPoAhJn5yy0GshPu8cRpC2fkoQ4Zy4c%2BMmHO7Tywow1YA3j%2FmMuI2guira6dt%2FPjWdoM3rg%3D%
3D"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
server: cloudflare
cf-ray: 6cd6a99a2d4042e7-FRA
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400
1 Like

Still the same.

curl -X HEAD -I https://tradingstrategy.ai
HTTP/1.1 200 OK
Date: Fri, 14 Jan 2022 11:54:32 GMT
Content-Type: text/html
Connection: keep-alive
Cache-Control: public, max-age=300
Link: </fonts3.css>; rel="preconnect", </_app/assets/start-6f5e0715.css>; rel="preconnect", </_app/assets/pages/__layout.svelte-f31b19cc.css>; rel="preconnect", </_app/assets/pages/index.svelte-84a34be8.css>; rel="preconnect"
Permissions-Policy: interest-cohort=()
Vary: Accept-Encoding
CF-Cache-Status: DYNAMIC
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=987hgA9zpkb4ZCtTEKhQPp5Uff0LQHUr5%2BdX8HvFAxAskq0gfETnuYOgcaucYtpQw4DiqwsYVO0QxVCM5NSPtmHUPRkeI87boXlZLrl5hUoIDPk0XGRgCnKF7FRWZgRGCZwHmg%3D%3D"}],"group":"cf-nel","max_age":604800}
NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Server: cloudflare
CF-RAY: 6cd6ab91db2d1505-MAD
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400

Must be a problem with my curl. This is Homebrew built for macOS.

I confirmed, curl from Ubuntu 20.04 Linux server correctly displays the headers:

/tmp # curl -X HEAD -I https://tradingstrategy.ai

HTTP/2 103
link: </fonts3.css>; rel=preconnect, </_app/assets/start-6f5e0715.css>; rel=preconnect, </_app/assets/pages/__layout.svelte-f31b19cc.css>; rel=preconnect, </_app/assets/pages/index.svelte-84a34be8.css>; rel=preconnect

Would there be anything in the network or CF that could affect curl’s behavior?

There are two possible cases now:

  1. This: Early Hints | Need More Data Before Switching Over - #21 by LucasCF
  2. your cURL version does not support HTTP2?

Can you please run curl --version and post the output?

But anyway: since i can confirm Cloudflare does send the 103 with the correct headers, this is not a Cloudflare problem.

1 Like
curl 7.71.1 (x86_64-apple-darwin13.4.0) libcurl/7.71.1 OpenSSL/1.1.1h zlib/1.2.11 libssh2/1.9.0
Release-Date: 2020-07-01
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS GSS-API HTTPS-proxy IPv6 Kerberos Largefile libz NTLM NTLM_WB SPNEGO SSL TLS-SRP UnixSockets

Thats not old and should support HTTP2 and 103 status codes. Can you please run the command:

curl -X HEAD -I https://tradingstrategy.ai multiple times (like 10 times) and see if after multiple times it gives a different result.

Even more simple would be:

curl -X HEAD -I https://tradingstrategy.ai 2>&1 | grep "HTTP/.*103"

This will output the headers pre-announcement if it is getting triggered. (It is not getting treiggered everytime)

Thank you Martin. I tried this earlier, no luck.

I am now reinstalling curl and see if there is an updated version available, and whether this will bring any change.

Please also have a read there: Early Hints | Need More Data Before Switching Over - #21 by LucasCF
Depending on where you are and how fast Cloudflare can get the requested file you will NOT get any 103 code, which makes sence if Cloudflare is very fast. But everytime the CF-Cache is dynamic it should trigger a 103, since then it would speed up the PageLoad.

But this problem seems to be related to your local installation, since it is working for me.

1 Like

Depending on where you are and how fast Cloudflare can get the requested file you will

This is helpful. I am located in Gibraltar. It is a funny little peninsula country with pretty bad Internet. I will try to run the same command over a different Internet connection later.

That curl version output doesn’t show any HTTP/2 support under Features listing it’s missing HTTP2

HTTP/2

curl -V
curl 7.80.0 (x86_64-redhat-linux-gnu) libcurl/7.80.0 NSS/3.67 zlib/1.2.7 libpsl/0.7.0 (+libicu/50.1.2) libssh2/1.10.0 nghttp2/1.33.0 OpenLDAP/2.4.44
Release-Date: 2021-11-10
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL UnixSockets

notice HTTP2 listed under Features section

and if HTTP2 and HTTP3 supported will look like

curl -V
curl 7.82.0-DEV (x86_64-pc-linux-gnu) libcurl/7.82.0-DEV BoringSSL zlib/1.2.11 brotli/1.0.7 zstd/1.5.1 libidn2/2.0.5 libpsl/0.20.2 (+libidn2/2.0.5) libssh2/1.8.0 nghttp2/1.41.0-DEV quiche/0.10.0 OpenLDAP/2.4.47
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Largefile libz NTLM NTLM_WB PSL SSL UnixSockets zstd
3 Likes

After updating curl, I can now see it works locally. It seems to have been a problem with a particular curl version that advertised HTTP/2 support with --http2 switch, but did not actually do this.

curl --version
curl 7.81.0 (x86_64-apple-darwin20.6.0) libcurl/7.81.0 (SecureTransport) OpenSSL/1.1.1m zlib/1.2.11 brotli/1.0.9 zstd/1.5.1 libidn2/2.3.2 libssh2/1.10.0 nghttp2/1.46.0 librtmp/2.3 OpenLDAP/2.6.0
Release-Date: 2022-01-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL TLS-SRP UnixSockets zstd
1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.