Angular-cli: [app-shell] Doesn't work together with @angular/service-worker: "Error: Hash mismatch (cacheBustedFetchFromNetwork)" (+ explanation, + solution)

Created on 8 Dec 2017  路  18Comments  路  Source: angular/angular-cli

cc: @alxhub @StephenFluin

Versions

Angular CLI: 1.6.0
Node: 8.2.1
OS: darwin x64
Angular: 5.1.0
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router

@angular/cli: 1.6.0
@angular-devkit/build-optimizer: 0.0.35
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.41
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.0
@schematics/angular: 0.1.10
@schematics/schematics: 0.0.10
typescript: 2.4.2
webpack: 3.10.0

Repro steps

Generate a new app with --service-worker, then generate Universal app, then generate app-shell (if it fails, use workaround from https://github.com/angular/angular-cli/issues/8793) and run in the browser

Observed behavior

At /ngsw/state:

NGSW Debug Info:

Driver state: EXISTING_CLIENTS_ONLY (Degraded due to failed initialization: Hash mismatch (cacheBustedFetchFromNetwork): http://localhost:8080/index.html: expected e809040220500c7210a197856aa3ecdf8ddd3618, got 100d6731232af53d7a592198666378360e223ba9 (after cache busting)
Error: Hash mismatch (cacheBustedFetchFromNetwork): http://localhost:8080/index.html: expected e809040220500c7210a197856aa3ecdf8ddd3618, got 100d6731232af53d7a592198666378360e223ba9 (after cache busting)
    at PrefetchAssetGroup.cacheBustedFetchFromNetwork (http://localhost:8080/ngsw-worker.js:657:27)
    at <anonymous>)
Latest manifest hash: 0f59e15ff1beb35d4ff048bb6cc056e34917081f
Last update check: 6m4s739u

Desired behavior

Same run/update SW behavior as with non-app-shell node

Mention any other details that might be useful (optional)

It happens because app-shell version of index.html generated after the generation of ngsw.json, where the hash of index.html located. So ngsw.json contains an incorrect hash, this is why @angular/service-worker throws this error after checking the integrity. Solution: make ngsw.json generation a last step in the flow.

1 (urgent) bufix

Most helpful comment

I realized that in my case, I used angular universal to pre-rending my app, something like this. It will modify the index.html and then change the file hash.

For example, before pre-rending, the sha1 hash for index.html was a85416190bba14b95f37685b1b0d7ccc8251f982 which matched the ngsw.json and it changed to 92cb3d0c8dd68b84e1747bdaa73982ecb8315748 when the pre-rending was done.

Just like @webmaxru said, you have to manually generate the ngsw.json again to make sure the hash matches:

./node_modules/.bin/ngsw-config dist src/ngsw-config.json

So I suggest that the CLI should have some options like --skip-service-worker and --service-worker-only to let the user decide when to use the NGSW.

All 18 comments

Seeing this too. My production version of the app became completely unresponsive. Had to roll back immediately.

For customers who downloaded this version of my app.... how do I make it update so they can see my site again?

error

Update: I think in our case it is actually because we do some string replacement after the dist has been created.

Update: No, fixed the string replacement and still getting the same error. Getting this error even without an app shell. I need to do some more digging. Might create a separate ticket for this.

Yes, unfortunately, this affects not only the SW, but the whole app.
But there is a kill-switch for NGSW: just remove ngsw.json from your deployment, and NGSW will clean-up all the caches and de-register itself.

I got the same error, but only when the guard for authentication returns false.
But there is no pattern: sometimes I get an ERR_FAILED message by chrome and after 3 seconds it loads the login page. Or the login page is loaded after 59ms without any error.

Update: after refreshing an authenticated page after some minutes it does not work neither.

These is definitely something fishy here. I deploy to production servers. I flush caches. I load. I can see that the service worker runs. I can refresh the page successfully. When I come back a while later, I can't hit the page at all. I have to do a hard refresh of the page or unregister service worker and then a normal refresh for it to load. Next time I refresh, it fails again.
error2
error

Definitely not working. I am on Firebase and using Cloudflare fyi.

i have the same problem with @bjornharvold index.html hash always invalid..

But I'm experiencing it on a VPS server with cloudflare

+1 for this

I realized that in my case, I used angular universal to pre-rending my app, something like this. It will modify the index.html and then change the file hash.

For example, before pre-rending, the sha1 hash for index.html was a85416190bba14b95f37685b1b0d7ccc8251f982 which matched the ngsw.json and it changed to 92cb3d0c8dd68b84e1747bdaa73982ecb8315748 when the pre-rending was done.

Just like @webmaxru said, you have to manually generate the ngsw.json again to make sure the hash matches:

./node_modules/.bin/ngsw-config dist src/ngsw-config.json

So I suggest that the CLI should have some options like --skip-service-worker and --service-worker-only to let the user decide when to use the NGSW.

Hi @PoiScript & @webmaxru.

Well, I did the opposite : implement the app shell and then implement the service worker : I've got the same issue with the hash codes.
You're right, it should be very cool to get an option helping to generate a new ngsw.json at the end of the build process.

any update on this ?

No. But the workaround is to Generate new ngsw.json

how will we generate new ngsw.json . it should part of the prod build right ?

It should but I guess it is not. Just execute : ./node_modules/.bin/ngsw-config dist src/ngsw-config.json

Priority: 1 (urgent)..... meanwhile 26 days later. :-D I just disabled SW until this is fixed. Great that there is a workaround out there though.

Thank you @skonx
Using your advice, I've then simply added the following npm script in package.json:

"ngsw:version": "ngsw-config dist/browser src/ngsw-config.json"

And then I've added it to the build script, after ng build --prod:

"build:ssr": "ng build --prod && ng build --prod --app 1 --output-hashing=false && npm run ngsw:version && cpy ./server.ts ./dist"

In my case it's dist/browser for the client app and dist/server for the Server Side Rendering app. Plus I have another (3rd app) for the app shell (since I can't use the existing universal/ssr app, it errors on build because of ModuleMapLoaderModule and some express imports, but that's another issue).

So, now on every build, after it finishes it also re-generates the ngsw.json file with the correct hash for index.html.
SSR + AppShell + ServiceWorker is working with this "workaround"! Scratch that! If I stop the server, on the next page refresh it stops working (see #21636). But that's a different issue, it doesn't seem to have anything to do with the hash/version.
There is one other issue, I remember seeing it on GitHub, just can't find it now, but I think it's documented: instead of the app shell component, it shows the 404 component (if you have a '**' path defined), unless you also add the AppShellComponent + route in your app routing module.

I have a similar problem where ngsw.json contains a number of wrong hashes (for .svg fonts and .css). Running ngsw-config again does not fix it. Could this be related?

When I fix these hashes manually and also apply the fix as detailed here: https://stackoverflow.com/a/48732922/4167438 then my app works offline, otherwise I get 504's on the main page and hash mismatches on the style and fonts.

currently using cli 1.6.8 and @angular/* 5.2.5

Has this been resolved in CLI 6? I still can't get app-shell and service worker to work together.

Since this problem never came up while testing with http-server -c-1 dist/ I just looked into apache-ws caching and this config in the httpd-vhosts.conf did solve it:

<Files ngsw-worker.js>
    FileETag None
    Header unset ETag
    Header set Pragma "no-cache"
    Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
    Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
  </Files>

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings