prisma: Library may be corrupt (missing `libz.so.1`) when using distroless Docker images

Bug description

When using prisma in gcr.io/distroless/nodejs18-debian11. I got this error

/app/node_modules/@prisma/client/runtime/index.js:34316
      throw new PrismaClientInitializationError(message, this.client._clientVersion);
            ^

PrismaClientInitializationError:
Invalid `prisma.user.count()` invocation in
/app/index.js:5:13

  2
  3 const prisma = new PrismaClient();
  4
→ 5 prisma.user.count(
Unable to load Node-API Library from /app/node_modules/.prisma/client/libquery_engine-debian-openssl-1.1.x.so.node, Library may be corrupt
    at RequestHandler.handleRequestError (/app/node_modules/@prisma/client/runtime/index.js:34316:13)  
    at /app/node_modules/@prisma/client/runtime/index.js:34737:25
    at async PrismaClient._executeRequest (/app/node_modules/@prisma/client/runtime/index.js:35301:22) 
    at async PrismaClient._request (/app/node_modules/@prisma/client/runtime/index.js:35273:16) {      
  clientVersion: '4.6.0',
  errorCode: undefined
}

How to reproduce

  1. Clone https://github.com/vimutti77/prisma-napi-distroless-bug
  2. Run npm run build
  3. Run npm run start
  4. See error

Expected behavior

It should no error and log count: 0

Prisma information

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int     @id @default(autoincrement())
  title     String
  content   String?
  published Boolean @default(false)
  author    User    @relation(fields: [authorId], references: [id])
  authorId  Int
}
const { PrismaClient } = require("@prisma/client");

const prisma = new PrismaClient();

prisma.user.count().then((count) => {
  console.log(`count: ${count}`);
});

Environment & setup

  • OS: gcr.io/distroless/nodejs18-debian11
  • Database: SQL Server
  • Node.js version: 18

Prisma Version

I got this error when I try to check the prisma version inside the docker container

Error: Unable to require(`/app/node_modules/@prisma/engines/libquery_engine-debian-openssl-1.1.x.so.node`)
 libz.so.1: cannot open shared object file: No such file or directory
    at load (/app/node_modules/prisma/build/index.js:89146:11)
    at getEngineVersion (/app/node_modules/prisma/build/index.js:89944:16)
Error: Command failed with exit code 127: /app/node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x --version
/app/node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory
    at makeError (/app/node_modules/prisma/build/index.js:3641:18)
    at handlePromise (/app/node_modules/prisma/build/index.js:4409:33)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)     
    at async getEngineVersion (/app/node_modules/prisma/build/index.js:89947:20) {    
  shortMessage: 'Command failed with exit code 127: /app/node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x --version',
  command: '/app/node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x --version',
  escapedCommand: '"/app/node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x" --version',
  exitCode: 127,
  signal: undefined,
  signalDescription: undefined,
  stdout: '',
  stderr: '/app/node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory',
  failed: true,
  timedOut: false,
  isCanceled: false,
  killed: false
}
Error: Command failed with exit code 127: /app/node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x --version
/app/node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory
    at makeError (/app/node_modules/prisma/build/index.js:3641:18)
    at handlePromise (/app/node_modules/prisma/build/index.js:4409:33)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)     
    at async getEngineVersion (/app/node_modules/prisma/build/index.js:89947:20) {    
  shortMessage: 'Command failed with exit code 127: /app/node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x --version',
  command: '/app/node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x --version',
  escapedCommand: '"/app/node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x" --version',
  exitCode: 127,
  signal: undefined,
  signalDescription: undefined,
  stdout: '',
  stderr: '/app/node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory',
  failed: true,
  timedOut: false,
  isCanceled: false,
  killed: false
}
prisma                  : 4.6.0
@prisma/client          : 4.6.0
Current platform        : debian-openssl-1.1.x
Query Engine (Node-API) : E_CANNOT_RESOLVE_VERSION (at node_modules/@prisma/engines/libquery_engine-debian-openssl-1.1.x.so.node)
Migration Engine        : E_CANNOT_RESOLVE_VERSION (at node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x)
Introspection Engine    : E_CANNOT_RESOLVE_VERSION (at node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x)
Format Binary           : prisma-fmt 2e719efb80b56a3f32d18a62489de95bb9c130e3 (at node_modules/@prisma/engines/prisma-fmt-debian-openssl-1.1.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.6.0-53.2e719efb80b56a3f32d18a62489de95bb9c130e3
Default Engines Hash    : 2e719efb80b56a3f32d18a62489de95bb9c130e3
Studio                  : 0.476.0

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 18 (6 by maintainers)

Commits related to this issue

Most upvoted comments

I faced same issue. this is my workaround: set up image tag explicitly to use alpine 3.16.

-FROM node:16-alpine
+FROM node:16-alpine3.16
WORKDIR /app
COPY --from=prod-build /app/prod_node_modules ./node_modules
COPY --from=build /app/dist              ./dist
COPY --from=build /app/prisma            ./prisma
COPY --from=build /app/package.json ./package.json

@vimutti77 a deeper inspection of this issue revealed that the Prisma Client fails to import the query engine because the libz system library dependency doesn’t exist on grc.io/distroless images.

From your reproduction, I see you’re using a multi-stage Docker build process, with node:18.12.1-bullseye-slim (aliased as deps) as your base image. When using the distroless image, should import the libz library from deps.

Assuming you’re running Docker on an amd64 machine, you can change the final part of your Dockerfile as:

FROM gcr.io/distroless/nodejs18-debian11:debug

# set working directory
WORKDIR /app/

# copy node_modules
COPY --from=deps /app/node_modules/ /app/node_modules/

# copy libz.so.1 from Debian, which was causing the
# "Library may be corrupt" error
COPY --from=deps /lib/x86_64-linux-gnu/libz.so.1 /lib/x86_64-linux-gnu/libz.so.1

# copy db & script
COPY prisma /app/prisma
COPY index.js /app/index.js

CMD ["/app/index.js"]

If you’re on arm64, simply substitute x86_64 in the libz.so.1 path with aarch64.

Thanks, now it works.

Maybe we should add about this in the documentation then close the issue?

@vimutti77 a deeper inspection of this issue revealed that the Prisma Client fails to import the query engine because the libz system library dependency doesn’t exist on grc.io/distroless images.

From your reproduction, I see you’re using a multi-stage Docker build process, with node:18.12.1-bullseye-slim (aliased as deps) as your base image. When using the distroless image, should import the libz library from deps.

Assuming you’re running Docker on an amd64 machine, you can change the final part of your Dockerfile as:

FROM gcr.io/distroless/nodejs18-debian11:debug

# set working directory
WORKDIR /app/

# copy node_modules
COPY --from=deps /app/node_modules/ /app/node_modules/

# copy libz.so.1 from Debian, which was causing the
# "Library may be corrupt" error
COPY --from=deps /lib/x86_64-linux-gnu/libz.so.1 /lib/x86_64-linux-gnu/libz.so.1

# copy db & script
COPY prisma /app/prisma
COPY index.js /app/index.js

CMD ["/app/index.js"]

If you’re on arm64, simply substitute x86_64 in the libz.so.1 path with aarch64.

For people mentioning node:16-alpine, please refer to this solution (the easiest one is upgrading to prisma@4.8.0).

Let’s keep the discussion on this issue focused on gcr.io/distroless/nodejs18-debian11 (and potentially other distroless images), thank you.

Is this a problem with docker or prisma?