Automatic Signed Exchanges (SXGs) Beta Launch

hmm from webpackager/ at main · google/webpackager · GitHub

Google SXG cache

The Google SXG cache sets these requirements in addition to the ones set by the SXG spec:

  • The SXG must have a freshness lifetime of at least 120 seconds, as computed for a shared cache from its outer headers.
  • The signed fallback URL must approximately equal the URL at which the SXG was served. Where possible, aim to make them byte-equal. The set of allowed differences is not precisely specified, but approximately:
    • Characters may be substituted by their percent encodings, and vice versa, with the exception of meaningful delimiters like / , ; , ? , & , and = .
    • Query parameters may be re-ordered.
    • Valueless query parameters may be encoded with or without a trailing = .
    • Extra & s in the query string are allowed.
  • The signed cert-url must be https .
  • The signature header must contain only:
    • One parameterised identifier.
    • Parameter values of type string, binary, or identifier.
  • The payload must be non-empty.
  • The signed cache-control header cannot have a no-cache or private directive, even with a value (e.g. no-cache=some-header is disallowed).
  • The content-type must satisfy the media-type grammar.
  • The link header, if present, must lead to successful substitution per the Loading spec. Specifically, it must meet these requirements, in addition to the ones set by the Link spec:
    • Each URI-Reference must be an absolute https URL.
    • Parameter names can only be as , header-integrity , media , rel , imagesrcset , imagesizes , or crossorigin .
    • All rel parameters must be either preload or allowed-alt-sxg .
    • All imagesrcset values must parse as a srcset attribute.
    • There may be no more than 20 rel=preload s.
    • All crossorigin values must either be the empty string, or anonymous .
    • Every rel=preload must have a corresponding rel=allowed-alt-sxg with the same URI, which in turn must contain a header-integrity parameter with a value that satisfies the CSP hash-source grammar using the sha256 variant.
    • The preloaded URLs, when requested with an SXG-preferring Accept header, must respond with valid SXGs that match their given header-integrity .
  • The link header must not be present on subresources, i.e. SXGs that are themselves preloaded from other SXGs.
  • There must not be a signed variant-key-04 or variants-04 header.
  • The signature’s lifetime ( expires minutes request time) must be >= 120 seconds.
  • The SXG must be no larger than 8 megabytes.
  • The page should be responsive, i.e. correct on all media. (In the future, a supported-media annotation should allow this constraint to be removed.)

Some of the above limitations are overly strict for an SXG cache’s needs, and were implemented as such for the sake of expediency. They may be loosened over time, especially in response to publisher feedback.

and rfc7234

4.2.1. Calculating Freshness Lifetime A cache can calculate the freshness lifetime (denoted as freshness_lifetime) of a response by using the first match of the following:

  • If the cache is shared and the s-maxage response directive (Section is present, use its value, or
  • If the max-age response directive (Section is present, use its value, or
  • If the Expires response header field (Section 5.3) is present, use its value minus the value of the Date response header field, or
  • Otherwise, no explicit expiration time is present in the response. A heuristic freshness lifetime might be applicable; see Section 4.2.2.

Not sure if CF follows this, but that would mean in order of priority would be cache-control s-maxage, max-age, expires? Looks like cdn-cache-control header isn’t supported then.

1 Like

So since we have HSTS enabled we will not be able to use signed exchanges?

Also, WordPress sites should have no issues with signed exchanges, correct?


Hi @jon28. This appears to be a Google bug. The problem is we are interpreting Cache-Control: must-revalidate as equivalent to max-age=0 . This seems wrong per the HTTP spec.

  1. Short term, you can remove the must-revalidate.
  2. Medium term, we’ll try to fix this bug or make some changes to remove must-revalidate.

cc @eva2000


Hi @Terms_G, I replied to the thread you’ve created. For visibility, I also put it here:

For “The dates for the signed exchange are invalid.” errors: You can ignore them. Google can still parse the SXG and treat it like normal HTML, so it falls back to earlier behavior.

For HSTS: There are Users [ @eva2000, @junellabanag1 ] reporting that SXGs is working on their websites even in the presence of HSTS. I will update you when we know more.


Hi folks. Regarding errors in the Search Console:
If it’s an AMP page, you can check out the AMP status report - Search Console Help, which explains the impact.

For non-AMP cases, or non-AMP SXGs customers, unfortunately, a nice help page doesn’t exist yet which would describe the error type breakdown, but if there are any critical errors that would warrant disabling SXGs:

  • You should be able to detect them for a specific URL by following the steps in Verify SXG Setup.
  • They should show up later in Search Console as "Fetch error"s, per Monitor and debug SXG.
1 Like

Hey Jon,

I have the same issue, my main content is set to cache at 2 minutes, my directory pages set to cache 20 days (confirmed via my headers that this is correct). Yet I am getting the same error as you

“debug: content has ingestion error: Error fetching resource: Content is not cache-able or cache-able lifetime is too short”

Thanks I can confirm that I am also getting this bug most likely due to must-revalidate

“Cache-Control: max-age=1728000, must-revalidate”

“debug: content has ingestion error: Error fetching resource: Content is not cache-able or cache-able lifetime is too short”

Thanks for the update :smiley:

1 Like

I did a write up of my own Cloudflare Automatic Signed Exchanges testing on my blog (which is SXG enabled) :sunglasses:

Also for checking to see if SXG is working, you can simply use Google Search Console and do a Mobile Usability URL Live Inspection of a URL link on your site and inspect the MORE INFO → HTTP Response (screenshot below) to check if content-encoding: mi-sha256-03 is displayed. Mobile Usability URL live inspection is done using Android Chrome so would fetch a Cloudflare generated SXG version if it’s available :slight_smile:


Great read! Thanks for sharing your expertise.

Tested mine on Google Search Console :grinning:

1 Like

Hi @firat,

I also posted this in the thread I created but I will post it on here as well.

I googled our site and indeed the SXG is working normally. The URL goes from the google URL then switches to our URL.

However, our logo is no longer in the search results for any AMP page. Is this normal behavior?

Thanks and regards.

You’re welcome. I’ve since updated my write up with more info :slight_smile:


Google search and Cloudflare Signed Exchange SXG cache pre-fetching in action :sunglasses: :nerd_face: :heart_eyes:


Thanks for the updates, Sir. I also followed you on Twitter :innocent:

1 Like

Hi folks.

I added a new section to the first post of thread: FAQs.



Great post, @eva2000. As always :slight_smile:

1 Like

Cheers :slight_smile:

Thanks for that :slight_smile:

Thanks. Updated my article with Webpagetest generated video demo of Cloudflare Signed Exchange being prefetched when loading Google Searched term – – notice how after clicking on the Google search result listing’s link, the WordPress blog page loading :sunglasses: instantly!

Seems this forum doesn’t support MP4 file attachments heh


awesome post thanks! :+1:

1 Like

Cheers :slight_smile:

@firat I want to do some tests before SXG enabled vs after SXG enabled. But I guess disabling SXG from CF dashboard isn’t enough? I’d need to wait for Google search cached SXG to expire on their end first too right?

Just curious, if my page has a 2 minute cache time, will Google serve the SXG only within a 2 minute period of indexing that page?