Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Error: crypto.getRandomValues() not supported on node.js #3950

Answered by au-z
maxbritto asked this question in Q&A
Discussion options

Hello,
I'm trying to migrate to v3 of the AWS S3 client on my node.js 18.8 app.

Whenever I try to use the PutObjectCommand to upload a file, I get this error : Error: crypto.getRandomValues() not supported

What is it that I am doing wrong here ?

Thank you!

You must be logged in to vote

@maxbritto - thanks for your succinct explanation. I was running into the same situation using vite and was able to work around this issue with a combination of rollup settings and a small polyfill borrowing some basic logic from the react-native-get-random-values polyfill.

Changes to vite.config.ts:

import { nodeResolve } from '@rollup/plugin-node-resolve'
export default defineConfig({
 build: {
 // ...
 rollupOptions: {
 output: {
 globals: {crypto: 'crypto'},
 },
 external: ['crypto'],
 plugins: [nodeResolve({ preferBuiltins: true })],
 },
 },
})

My understanding is that these settings will direct the build/bundle to use the nodejs crypto module i...

Replies: 10 comments 5 replies

Comment options

Can you please share your actual code including import statements?
Hard to say what could go wrong.

Perhaps erase your package.json file and run npm init again?

You must be logged in to vote
0 replies
Comment options

Thank you for your answer, here is the code I'm using :

import {
 S3Client,
 PutObjectCommand,
 PutObjectCommandInput
 } from "@aws-sdk/client-s3";
import { env } from "process";
export class CdnManager {
 readonly cdnBaseUrl: string = env.S3_ENDPOINT;
 readonly cdbBucketName: string = env.S3_BUCKET_NAME;
 private getS3Client() : S3Client {
 return new S3Client({region:"auto", endpoint:this.cdnBaseUrl, apiVersion: '2006-03-01', credentials: {accessKeyId:env.S3_ACCESS_KEY_ID, secretAccessKey:env.S3_SECRET_ACCESS_KEY} });
 }
 async upload(destinationFilePath: string, body: string, contentType: string = "text/plain; charset=utf-8") {
 if (destinationFilePath.startsWith("/")) {
 destinationFilePath = destinationFilePath.substring(1);
 }
 console.log(`cdn upload to`,destinationFilePath);
 const uploadParams:PutObjectCommandInput = {
 Bucket: this.cdbBucketName,
 Key: destinationFilePath,
 Body: Buffer.from(body),
 ContentType: contentType
 };
 
 try {
 const s3 = this.getS3Client();
 const command = new PutObjectCommand(uploadParams);
 const result = await s3.send(command);
 console.log("Upload Success", result.$metadata);
 } catch (error) {
 console.log("Upload : Error was received for file at ", destinationFilePath, error);
 }
 }
}

This class is within an internal library with this package.json :

{
 "name": "learning-app-data",
 "version": "1.0.0",
 "description": "Data used in the learning app project",
 "main": "src/index.ts",
 "scripts": {
 "test": "node --inspect-brk node_modules/.bin/jest --runInBand"
 },
 "author": "Maxime Britto",
 "license": "ISC",
 "devDependencies": {
 "@types/jest": "^27.5.1",
 "@types/node": "^18.7.13",
 "jest": "^28.1.0",
 "ts-jest": "^28.0.2"
 },
 "dependencies": {
 "@aws-sdk/client-s3": "^3.170.0",
 "@directus/sdk": "^9.12.1",
 "teachable-api": "file:/Users/mbritto/code/node_projects/teachable-api"
 }
}

This library is the only dependency of a Directus extension with this package :

{
	"name": "directus-extension-elements-hooks",
	"version": "1.0.0",
	"keywords": [
		"directus",
		"directus-extension",
		"directus-custom-hook"
	],
	"directus:extension": {
		"type": "hook",
		"path": "dist/index.js",
		"source": "src/index.ts",
		"host": "^9.12.1"
	},
	"scripts": {
		"build": "directus-extension build",
		"dev": "directus-extension build -w --no-minify"
	},
	"dependencies": {
		"learning-app-data": "file:../learning-app-data"
	},
	"devDependencies": {
		"@directus/extensions-sdk": "9.12.1",
		"@types/node": "^17.0.41",
		"typescript": "^4.7.3"
	}
}

Which itself is used by the Directus server :

{
 "name": "teachable-app-webservice",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
 "dev": "npx nodemon --legacy-watch --exec NODE_OPTIONS=--inspect directus start",
 "start": "npx directus start",
 "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [],
 "author": "",
 "license": "ISC",
 "dependencies": {
 "@directus/sdk": "^9.0.0",
 "directus": "^9.0.1",
 "firebase-admin": "^10.0.2",
 "mysql": "^2.18.1",
 "sharp": "^0.30.4"
 }
}

I've tried your recommandation and removed the package.json and the package-lock.json then redid the whole npm init and npm install for my library which is using the S3-client library.
The problem remains.
I'm on macOS 12.5 with Node 18.8.0

After 3 hours of research here is the summary of my findings :

That is why I posted here, I could not find any more information on how to fix this issue.

Thanks for your help!

You must be logged in to vote
2 replies
Comment options

@maxbritto I'm also running into the same issue, also with Directus, and I'm also building a custom hook.

  • node -> 16.11.1
  • @aws-sdk/client-cognito-identity-provider -> 3.180.0
  • directus -> 9.18.1
Comment options

Well I gave up and went back to the aws sdk v2.
I hope it will be fixed at some point in the future and I will be able to migrate to it at that point

Comment options

@maxbritto - thanks for your succinct explanation. I was running into the same situation using vite and was able to work around this issue with a combination of rollup settings and a small polyfill borrowing some basic logic from the react-native-get-random-values polyfill.

Changes to vite.config.ts:

import { nodeResolve } from '@rollup/plugin-node-resolve'
export default defineConfig({
 build: {
 // ...
 rollupOptions: {
 output: {
 globals: {crypto: 'crypto'},
 },
 external: ['crypto'],
 plugins: [nodeResolve({ preferBuiltins: true })],
 },
 },
})

My understanding is that these settings will direct the build/bundle to use the nodejs crypto module instead of some polyfill which likely either shims or does not fully implement crypto.

In my application code, I first import this polyfill so it's run before any transitive deps are imported:

import './polyfills/crypto'
// rest of application code

The polyfill:

import crypto from 'crypto' // should have webcrypto.getRandomValues defined
if (typeof global.crypto !== 'object') {
 global.crypto = crypto
}
if (typeof global.crypto.getRandomValues !== 'function') {
 global.crypto.getRandomValues = getRandomValues
}
function getRandomValues(array) {
 return crypto.webcrypto.getRandomValues(array)
}

Hope this helps to diagnose and fix in your own project!

You must be logged in to vote
0 replies
Answer selected by RanVaknin
Comment options

@au-z solution worked for me, at directus operator extension. Hope AWS will fix it in a better manner soon.

You must be logged in to vote
1 reply
Comment options

Could you share the code you used? i'm having the same issue, but I'm not using rollup.

Comment options

if you are using rollup, this may caused by a resolving issue. update the plugin config in your rollup.config.js to:

{
 // ...other configs
 plugins: [
 // ...other plugins
 nodeResolve({ exportConditions: ['node'] })
 ]
}

which worked for me. see uuidjs/uuid#544 (comment)

You must be logged in to vote
0 replies
Comment options

Hello! Reopening this discussion to make it searchable.

You must be logged in to vote
0 replies
Comment options

What would you do in the instance where you're not using rollup?

You must be logged in to vote
0 replies
Comment options

I found an answer from a similar problem that another library had: jsdom/jsdom#1612

Basically add this so the dependency can find crypto:

import { Crypto } from "@peculiar/webcrypto"
global.crypto = new Crypto()
You must be logged in to vote
0 replies
Comment options

I was able to get passed this issue by installing 'react-native-get-random-values' and importing and then rebuilding it

to install

npm install react-native-get-random-values --save

adding the import line in the file that's calling the aws

import 'react-native-get-random-values';
You must be logged in to vote
2 replies
Comment options

This fixed the issue for me.

Comment options

this worked for me too

Comment options

I had this error in an AWS lambda function. I was using Node v18.x and when I bumped to Node v22.x everything worked fine.

If you are finding this error in another environment, just make sure that environments node version is high enough to support this (v20 might work too?).

If you can't do that, and are using vite then maybe something like https://www.npmjs.com/package/vite-plugin-node-polyfills would help you.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /