Skip to main content

Troubleshooting

This guide covers common issues encountered when deploying L{CORE} infrastructure and their solutions.

Architecture Issues

exec format error

Symptoms:

  • Container starts then immediately exits
  • Logs show: exec format error
  • No application logs appear

Cause:

Docker image was built for the wrong CPU architecture. This commonly happens when:

  • Building on Apple Silicon (M1/M2/M3) which uses ARM64
  • Deploying to cloud infrastructure that uses AMD64 (x86_64)

Solution:

Always specify the target platform when building:

# For Cartesi node
docker build --platform linux/amd64 -f node.dockerfile -t your-image .

# For Attestor
docker buildx build --platform linux/amd64 -f attestor.dockerfile -t your-image .

Prevention:

Add platform specification to all build scripts and CI/CD pipelines:

# In your build script
export DOCKER_DEFAULT_PLATFORM=linux/amd64

Encryption Issues

Decryption Failures

Symptoms:

  • "Failed to decrypt input" errors in Cartesi logs
  • "Action is required in payload" error (looking for action field in encrypted envelope)
  • Device attestations rejected

Possible Causes:

  1. Private key not baked into Dockerfile
  2. Key baking used ARG instead of ENV
  3. Mismatched keypair (public key in Attestor doesn't match private key in Cartesi)

Diagnosis:

Check if the key is actually in the machine image:

cat .cartesi/image/config.json | jq '.env'

Look for LCORE_INPUT_PRIVATE_KEY. If it's empty or missing, the key wasn't baked correctly.

Solution:

Hardcode the private key directly in your Cartesi Dockerfile:

ENV LCORE_INPUT_PRIVATE_KEY=your-base64-encoded-private-key

Then rebuild:

npx cartesi build

See Encryption Key Configuration for detailed instructions.

Empty Private Key After Build

Symptoms:

  • .cartesi/image/config.json shows LCORE_INPUT_PRIVATE_KEY= (empty string)
  • Decryption fails even though you added the key

Cause:

Used ARG + ENV pattern without the key being present at build time:

# This pattern is UNRELIABLE with Cartesi CLI
ARG LCORE_INPUT_PRIVATE_KEY
ENV LCORE_INPUT_PRIVATE_KEY=${LCORE_INPUT_PRIVATE_KEY}

Solution:

Use direct ENV assignment instead:

# This pattern is RELIABLE
ENV LCORE_INPUT_PRIVATE_KEY=your-actual-key-value

The Cartesi Machine requires deterministic builds, and the key must be present in the Dockerfile itself.


Template Hash Issues

Template Hash Mismatch

Symptoms:

  • Inputs are submitted but never processed
  • GraphQL shows inputs but processed_input_count: 0
  • No errors in logs, just silence
  • Contract interactions succeed but nothing happens

Cause:

The Cartesi machine code was changed, creating a new template hash, but the smart contracts still reference the old template hash.

Understanding Template Hashes:

The template hash is a cryptographic commitment to your Cartesi machine image. It changes when:

  • Any code in your application changes (.ts, .js, .py files, etc.)
  • Any ENV value in the Dockerfile changes
  • Dependencies are updated
  • The Dockerfile itself changes

Smart contracts verify that inputs come from machines with the expected template hash.

Diagnosis:

Check your current template hash:

npx cartesi hash

Compare this with the template hash in your deployed contracts.

Solution:

Deploy new contracts with the updated template hash:

npx cartesi deploy --hosting self-hosted

See Cartesi Deployment documentation for network-specific options.

Then update your configuration with the new contract addresses.

When Do I Need New Contracts?

Change TypeTemplate Hash Changes?New Contracts Needed?
Application code changesYesYes
Dockerfile ENV changesYesYes
npm/pip dependency updatesYesYes
External .env file changesNoNo
Attestor code changesNoNo
Node infrastructure changesNoNo

Database Issues

"type 'OutputEnum' already exists"

Symptoms:

  • Cartesi node exits immediately on startup
  • Error mentions database migration failure
  • type "OutputEnum" already exists in logs

Cause:

PostgreSQL schema from a previous deployment is conflicting with the new deployment.

Solution:

Clear the database schema:

DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;

Or use a fresh database for the new deployment.

"prepared statement already exists"

Symptoms:

  • Database connection errors
  • prepared statement "__diesel_stmt_0" already exists
  • Cartesi node fails to start

Cause:

Using a transaction pooler (typically port 6543 on Supabase) instead of a session pooler. The Diesel ORM used by Cartesi requires prepared statement support, which transaction poolers don't provide.

Solution:

Switch to the session pooler endpoint:

# Before (broken) - Transaction pooler
CARTESI_POSTGRES_ENDPOINT=postgresql://user:pass@host:6543/postgres

# After (working) - Session pooler
CARTESI_POSTGRES_ENDPOINT=postgresql://user:pass@host:5432/postgres

On Supabase:

  • Port 6543 = Transaction pooler (PgBouncer transaction mode)
  • Port 5432 = Session pooler or direct connection

EigenCloud-Specific Issues

App Not Updating After Redeploy

Symptoms:

  • Deployed new image but behavior unchanged
  • Old bugs still present after fix deployment
  • Configuration changes not taking effect

Cause:

EigenCloud may cache Docker images. Upgrading an existing app may not pull the latest image.

Solution:

Deploy as a new app with a different name instead of upgrading:

# Instead of upgrading
ecloud compute app upgrade --name my-app --image-ref new-image

# Deploy as new app
ecloud compute app deploy --name my-app-v2 --image-ref new-image --env-file .env

After verifying the new deployment works, terminate the old app.

Wallet Has No Funds

Symptoms:

  • Transactions fail with "insufficient funds for transfer"
  • Contract deployment fails
  • Attestor cannot submit inputs

Cause:

Each deployment may derive wallet addresses from mnemonics. A new deployment might be using a wallet that hasn't been funded.

Solution:

  1. Check the wallet address being used (check logs or configuration)
  2. Fund the wallet with native tokens (e.g., ETH on Arbitrum Sepolia)
  3. Verify balance before testing

For testnet deployments, use the appropriate faucet for your network.


Diagnostic Commands

Check Cartesi Machine Configuration

# View environment variables baked into the machine
cat .cartesi/image/config.json | jq '.env'

# Verify template hash
npx cartesi hash

See Cartesi CLI documentation for more commands.

Check Running Containers

# View container logs
docker logs <container-id>

# Check if container is running
docker ps -a | grep <image-name>

# Inspect container
docker inspect <container-id>

Test Cartesi Node Connectivity

# Health check (if exposed)
curl http://<node-ip>:<port>/health

# Query inspect endpoint
curl http://<node-ip>:<port>/inspect/<query-path>

# Check GraphQL endpoint
curl -X POST http://<node-ip>:<port>/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ inputs { totalCount } }"}'

Test Attestor Connectivity

# Health check
curl http://<attestor-ip>:<port>/health

# Check encryption status
curl http://<attestor-ip>:<port>/status

Verify Docker Image Architecture

# Check image architecture
docker inspect <image> | jq '.[0].Architecture'

# Should output: "amd64" for cloud deployments

Getting Help

If you're still stuck:

  1. Check the Cartesi documentation: docs.cartesi.io
  2. Review template hash: Run npx cartesi hash and compare with deployed contracts
  3. Verify key baking: Check .cartesi/image/config.json for your keys
  4. Check architecture: Ensure images are built for linux/amd64

Next Steps