Skip to content

cocoon-worker-release-latest is not reproducible from source — TEE_IMAGE_HASH mismatch blocks all new GPU hosts #69

Description

@sponomarenko

Summary

The published cocoon-worker-release-latest.tar.xz produces a TEE_IMAGE_HASH that is not registered in the production root contract. Building from the same source commit (9060ce5) using the documented reproducible build (./scripts/build-image prod) yields a third, different hash. As a result, no one running publicly-available code can pass the worker_hash_is_valid check on-chain.

Environment

  • Server: Dell PowerEdge XE9680, 8x NVIDIA H200 SXM 141GB + 4x NVSwitch
  • CPU: 2x Intel Xeon Platinum 8558 (Emerald Rapids, TDX-capable)
  • Host OS: Ubuntu 25.10, kernel 6.17.0-19-generic
  • QEMU: 10.1.0
  • mkosi: 25.3
  • Cocoon release: cocoon-worker-release-9060ce5.tar.xz (commit 9060ce5, Last-Modified Sat, 11 Apr 2026 18:29:07 GMT)
  • TDX: Initialized (virt/tdx: module initialized, kvm_intel.tdx=Y)
  • GPU CC mode: Enabled on all 8 H200s

All GPU/TDX/Intel SGX-DCAP/PCCS infrastructure is functional. RA-TLS certificates generate correctly, seal-server attestation passes, sglang inference server boots and serves test requests.

Reproduction

Followed README.md exactly:

wget https://ci.cocoon.org/cocoon-worker-release-latest.tar.xz
tar xf cocoon-worker-release-latest.tar.xz
cd release-9060ce5
./bin/seal-server --enclave-path ./bin/enclave.signed.so &
cp worker.conf.example worker.conf
# edit worker.conf with our owner_address, gpu, model, hf_token, etc.
./scripts/cocoon-launch worker.conf

worker.conf:

[node]
type = worker
model = Qwen/Qwen3-32B@9216db5781bf21249d130ec9da846c4624c16137:a3782505b11f4cb89c220933e80c151969965ef67509bc98dd2fa20daa166728
owner_address = UQDkVjgpqzj8OuOu4_8d88vyGMrh7lFBtMqUYSJIEy82od9d
gpu = 0000:19:00.0
node_wallet_key = ...
hf_token = ...
ton_config = /opt/cocoon/release-9060ce5/mainnet.cocoon.global.config.json
root_contract_address = EQCns7bYSp0igFvS1wpb5wsZjCKCV19MD5AVzI4EyxsnU73k

Observed behavior

cocoon-worker-runner.service crashes with:

worker-runner[1651]: Check `c->root_contract_config->has_worker_hash(local_image_hash_unverified_)` failed

Computed TEE_IMAGE_HASH:

EM9UIhzi5nT5bAyN+OfQ5ctLf9e2/m7fUsf+7qQBmHs=
hex: 10cf54221ce2e674f96c0c8df8e7d0e5cb4b7fd7b6fe6edf52c7feeea401987b

On-chain check via TON Center:

curl -s "https://toncenter.com/api/v3/runGetMethod" -X POST -H "Content-Type: application/json" -d '{
  "address":"EQCns7bYSp0igFvS1wpb5wsZjCKCV19MD5AVzI4EyxsnU73k",
  "method":"worker_hash_is_valid",
  "stack":[{"type":"num","value":"7603323586114790364894868202345832479141369465407458134401589376456734120059"}]
}'
# {"gas_used":2417,"exit_code":0,"stack":[{"type":"num","value":"0x0"}]}

0x0 = not in the whitelist.

Reproducible build investigation

Following the ## Reproducible Build section of README.md:

git clone https://github.com/TelegramMessenger/cocoon.git
cd cocoon
git submodule update --init --recursive
./reprodebian/fetch-deps.sh
./scripts/build-image prod

Build completed successfully. Comparing SHA-256 of generated images vs. the public tarball:

File Public release Built from source Match
OVMF.fd 7e2417e6... 7e2417e6...
image.vmlinuz f34f19b9... f34f19b9...
image.initrd 24181782... 24181782...
image.cmdline c5945795... 922c71c1...
image.img f6990698... 2aa1ba8f...

Full hashes:

Public release
7e2417e61d894e8733250f23ef35fa00197846dad33e33dbbf4698613c107d02  OVMF.fd
f34f19b9c7f4b310fd3ff2948fbfdcecbfb2abf9eca32b1812d3f1e130581728  image.vmlinuz
24181782e6045b242cb31ffbb91b698314debdfdea5244d0faf044e27518edbd  image.initrd
c59457958b55c4e657b2cc052fb42f9d54bab4997984942c4064784d6adfa9d7  image.cmdline
f6990698a9778b8691cd5ed4d616aebe465173ab4a0acb5453f79a121230a425  image.img
Built from source (commit 9060ce5)
7e2417e61d894e8733250f23ef35fa00197846dad33e33dbbf4698613c107d02  OVMF.fd
f34f19b9c7f4b310fd3ff2948fbfdcecbfb2abf9eca32b1812d3f1e130581728  image.vmlinuz
24181782e6045b242cb31ffbb91b698314debdfdea5244d0faf044e27518edbd  image.initrd
922c71c1481ee2e2fc89a73e7c1edd2dd9dea5092fdbdeeb27d49fa984127c91  image.cmdline
2aa1ba8f10c7fad1fe2a63499b2a8936074c2eca3309b358be71cfd1bb138448  image.img

Diff in image.cmdline is only the roothash= parameter (which is the dm-verity hash of image.img):

- roothash=13e35597b3d085fc56c08c57d2877f26b1ef9a73b720a6f7ff134cfab0241c37 ...
+ roothash=e09d4244b88efce344265367aee8046011d3be0faa0b27ea628ab6bb870ee679 ...

So image.img is the only file that genuinely differs. Everything else (kernel, initrd, OVMF) builds bit-identical.

mkosi.conf pins everything you'd expect: Snapshot=20260408T203914Z, SourceDateEpoch=0, all NVIDIA packages pinned to 595.58.03-1, kernel pinned to 6.19.10-1~bpo13+1, mkosi commit pinned. Submodule commits are tracked. The non-reproducibility of image.img appears to be a bug in the build pipeline.

Impact

There are currently 3 distinct TEE_IMAGE_HASH values for the "same" release-9060ce5:

  1. Hash A — what the Cocoon CI built and registered on-chain (unknown to us)
  2. Hash BEM9UIhzi5nT5bAyN+OfQ5ctLf9e2/m7fUsf+7qQBmHs= — what running the published tarball produces
  3. Hash Cwhatever local mkosi rebuild produces — what ./scripts/build-image prod produces today

Only Hash A is in the on-chain whitelist (last addWorkerType was fa928fc1b9d5945eec827efdafcc5c79052108e51dd11e98aac2b4204c09328c on 2026-04-12 07:14 UTC, which doesn't match B or C).

This means: no GPU host onboarding from the published artifacts works right now. The full attestation/cryptography stack works perfectly; the only failing check is worker_hash_is_valid against the root contract.

Suggested fixes

Any one of these would unblock onboarding:

  1. Fix the reproducibility of image.img so that ./scripts/build-image prod from a tagged commit produces the exact same bytes as cocoon-worker-release-<commit>.tar.xz, and ensure the registered on-chain hash matches that build.
  2. Register Hash B on-chain (the hash of the currently-published tarball: EM9UIhzi5nT5bAyN+OfQ5ctLf9e2/m7fUsf+7qQBmHs= / 0x10cf54221ce2e674f96c0c8df8e7d0e5cb4b7fd7b6fe6edf52c7feeea401987b). This will at least let anyone running the public release work.
  3. Publish SHA256SUMS for each release on ci.cocoon.org and document the canonical TDX measurement so hosts can verify what they're running matches what's registered.
  4. Add a CI step that, for every release, computes TEE_IMAGE_HASH from the produced artifacts and includes it in the release manifest.

Happy to share build logs, attestation reports, or run any further experiments. Thanks for the work on Cocoon, once the registration path is unblocked, this server will join the network.

@ubique @arseny30

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions