15

I've recently ran into this error with the google cloud storage SDK on Node.js. I know for a fact that this worked in the past without any changes, but I haven't touched the code in a while and might be wrong.

Here's the error itself:

Error: error:1E08010C:DECODER routines::unsupported
    at Sign.sign (node:internal/crypto/sig:131:29)
    at Object.sign (node_modules/jwa/index.js:152:45)
    at Object.jwsSign [as sign] (node_modules/jws/lib/sign-stream.js:32:24)
    at GoogleToken.requestToken (node_modules/gtoken/build/src/index.js:232:31)
    at GoogleToken.getTokenAsyncInner (node_modules/gtoken/build/src/index.js:166:21)
    at GoogleToken.getTokenAsync (node_modules/gtoken/build/src/index.js:145:55)
    at GoogleToken.getToken (node_modules/gtoken/build/src/index.js:97:21)
    at JWT.refreshTokenNoCache (node_modules/google-auth-library/build/src/auth/jwtclient.js:172:36)
    at JWT.refreshToken (node_modules/google-auth-library/build/src/auth/oauth2client.js:153:24)
    at JWT.getRequestMetadataAsync (node_modules/google-auth-library/build/src/auth/oauth2client.js:298:28) {
  library: 'DECODER routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_UNSUPPORTED'
}

The code that throws this error is the following:

const credentials = {
    type: process.env.TYPE,
    project_id: process.env.PROJECT_ID,
    private_key_id: process.env.PRIVATE_KEY_ID,
    private_key: process.env.PRIVATE_KEY,
    client_email: process.env.CLIENT_EMAIL,
    client_id: process.env.CLIENT_ID,
    auth_uri: process.env.AUTH_URI,
    token_uri: process.env.TOKEN_URI,
    auth_provider_x509_cert_url: process.env.AUTH_PROVIDER_X509_CERT_URL,
    client_x509_cert_url: process.env.CLIENT_X509_CERT_URL,
  };

  const storage = new Storage({
    credentials,
  });
  if (!req.file) {
    logger('POST /profile_image', logLevels.error, 'No file uploaded!');
    ResponseError.badRequest(res);
  }
  const bucketName = process.env.BUCKET_NAME;
  const bucket = storage.bucket(bucketName);
  const fileName = `profile_pics/${req.user}/${req.file.originalname}`;
  const file = bucket.file(fileName);
  const stream = file.createWriteStream({
    metadata: {
      contentType: req.file.mimetype,
    },
  });
  stream.on('error', (err) => {
    console.error('Error pushing the picture: ', err); <--- error
    throw err;
  });
  stream.on('finish', () => {
    return file.makePublic().then(async () => {
       ...
      })
  });
  stream.end(req.file.buffer);

The process.env contains all the right values, I've made sure to try with a new private key but same error. Has anyone seen this one before?

TIA!

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
Fares
  • 893
  • 1
  • 11
  • 24
  • 5
    1) Do not store service accounts in environment variables. 2) If you do, do not break the service account into pieces. Base64 encode the entire service account, store it in a variable, and then Base64 decode it when required. 3) Your code is failing because the client is being set up with bad credentials. Most likely a corrupted private key. – John Hanley Oct 19 '22 at 20:59
  • Was the issue a corrupted private key? – John Hanley Oct 19 '22 at 21:48
  • I cannot say. I encoded as you advised me to and the problem seemed to have disappeared. I'm beginning to think that maybe the breaking down into pieces part may have corrupted the individual keys. – Fares Oct 19 '22 at 22:02
  • 1
    I am fairly confident you corrupted the **private_key** field based on the stack trace. – John Hanley Oct 19 '22 at 22:04

4 Answers4

33

I got same issue and fixed it by replacing raw \n character with the newline character. Probably you get the key as raw data from your environment and \n character in the raw is not treated as a newline character. You can try this:

    private_key: process.env.PRIVATE_KEY.split(String.raw`\n`).join('\n'),

techstack
  • 520
  • 1
  • 4
  • 9
  • 1
    In local i was able to use the .env normally, but when i deployed to cloud run it failed. This worked for me in local and in cloud run, but why this happend? Can you explain it to me please? I tried to see what it does by printing it in console, but i cant see difference – JuanDa237 Feb 28 '23 at 06:06
  • I had to downgrade to node 16.16.0 and implement this: process.env.PRIVATE_KEY.split(String.raw`\n`).join('\n'), both changes were necessary in my case – Marcelo Vargas Z. Mar 30 '23 at 00:37
  • or `.replace(/\\n/g, '\n')` – dovid Jul 22 '23 at 19:45
14

Answering this as community wiki. As mentioned above in comments by John Hanley

  1. Do not store service accounts in environment variables.
  2. If you do, do not break the service account into pieces. Base64 encode the entire service account, store it in a variable, and then Base64 decode it when required.
  3. Your code is failing because the client is being set up with bad credentials. Most likely a corrupted private key.
Roopa M
  • 2,171
  • 4
  • 12
2

I think you need to check the .env file and make sure you don't have any extra characters added to the private key for example a comma "," at the end. that's the reason i was getting this error for me .

nodisplayname
  • 71
  • 1
  • 5
0

If you have recently upgraded your openssl to version 3, you may have to enable legacy certs in the /etc/ssl/openssl.cnf file:

   openssl_conf = openssl_init
   
   [openssl_init]
   providers = provider_sect
   
   [provider_sect]
   default = default_sect
   legacy = legacy_sect
   
   [default_sect]
   activate = 1
   
   [legacy_sect]
   activate = 1

This information is from the OpenSSL WIKI

bobmcn
  • 1,027
  • 9
  • 23