The "Body does not pass verification" error from a Motoko canister

Hi, Guys
I’m trying to write a http canister with Motoko. After I deployed it to IC network, I got the “Body does not pass verification” error when I access from browser.
Canister ID: p5th4-gyaaa-aaaal-qajkq-cai
URL of problem:
The RAW URL works fine:
My code: TinTinLectures-Lesson3/ at master · wewei/TinTinLectures-Lesson3 (

From this topic
Service Worker Bug? Body does not pass verification - Developers - Internet Computer Developer Forum (

I learned this error has something to do with the service worker. I debugged into the SW, found the response has no IC-Certificate header. But I don’t understand why.

Could anybody help me on this? Or, even better, share some document/ post/ sample code about how the http_request work.


These articles will have some good info for you:

I’d love to see a reference implementation of a motoko file server, so please revert if you get it figured out! I think you are going to have to use the certified data api.


Thank you, I’ll read the threads first as well as the ic-certified-assets to get more background.

Maybe too minimal to count as a “reference implementation”, but could be a starting point.

1 Like

This is great. I’ll use this for my http_request lecture for the bootcamp.

It would also probably be worth a bounty to flesh it out to a full file server.

One thing that has occurred to me on reading this is that it may be hard(impossible?) to do this for dynamic http responses. Say you serve a page with a time stamp on it. You wouldn’t be able to provide a certified tree with the content of the page because http_request is a query and you would not be able to update it. For dynamic content I guess we’ll always have to use raw?

Correct, and one of my main criticisms of the whole “certified variables” approach to securing queries. I haven’t given up hope that we get proper, system-provided “certified queries” at some point, where the boundary node aggregates the query response from multiple nodes (multi- or threshold signature). This would allow any query to be used securely (even dynamic ones) without any effort on the canister authors side, actually fulfilling the promise of a tamper-proof, easy to use platform. In fact, I’d argue it should be the default. No more raw!

And I’d bet that such a feature would have been less effort than all the work that went into certified variables across the stack and in terms of education.

Maybe one day - someone observed that it’d be internally needed or at least useful for implementing inter-canister query calls, so I’m not giving up hope.


You could use http_request_update :slightly_smiling_face:


For your original question, here are your possible next steps

  1. Read up on certified variable (videos and documentation)
  2. Look at rust asset canister for a reference implementation

Decide if you need the performant certified queries ? Queries are performant but are hard to implement in a “secure” fashion. You can fall back to updates if you don’t need the speed.

Relying on raw path to access uncertified queries is relies on a “unintended omission” and will be fixed anytime time and your raw accessed will ALSO start to fail.

Please reach out to the community for implementing queries securely with certificates. Falling back to raw path for insecure access to queries is a anti-pattern and is relies on a behavior which will be fixed anytime in near future.

IMO a lot of important aspects are getting buried under this infamous error code body cannot be verified

  1. Insecurity of non-certified queries
  2. Difficulty in implementing certified response . (This is a known unspoken issue - designing certified queries is orders of magnitude more arduous than coding any other aspect of a IC canister)
  3. confusion around spec of raw/non-raw mandatory non-mandatory aspects of certificate generation and checking. This is the part that can be easily fixed.

I don’t believe throwing boundary nodes into mix brings any clarity to the situation. Boundary nodes should best serve as performance enhancements and not turn into a core requirement/extension for the IC protocol. At least, until they are completely decentralized.

I keep talking about this issue all the time :slight_smile:

(I wish someone at DFINITY would make this document public, it discusses the issue with certified variables, and might be helpful for anyone digging deeper. But a TL;DR of it is in my post above.)

1 Like

I’m still a bit confused as to if this is natively handled or if it only works with the ICX proxy. Will this get hit for any HTTP request that is not a get natively?

My particular use case involves images and having them return in query time is pretty important. Waiting for consensus is going to make the page crawl.

Does this mean that raw access will go away in the future?

1 Like

This was the last I heard from @faraz.shaikh: