16

I have a strange redis behavior:

const redis = require('redis');
const { REDIS_URL: redisUrl, REDIS_PASSWORD: redisPassword } = process.env;

const client = redis.createClient(redisUrl, {
  no_ready_check: true,
  auth_pass: redisPassword
});

client.on('connect', () => {
  redisPassword && client.auth(redisPassword);
});

client.on('error', err => {
  global.console.log(err.message)
});

But all the time I receive following error:

throw er; // Unhandled 'error' event

ReplyError: Ready check failed: NOAUTH Authentication required.

Why unhandled ? I set onerror handler
Why Ready check failed ? I disabled it in options

Community
  • 1
  • 1

4 Answers4

19

I'm not sure why your code will throw this error. But I try this code in my local machine, it works well.

const redis = require('redis');
const redisPassword = "password" ; 
const client = redis.createClient({
          host : '127.0.0.1',  
          no_ready_check: true,
          auth_pass: redisPassword,                                                                                                                                                           
});                               
                                  
client.on('connect', () => {   
          global.console.log("connected");
});                               
                                  
client.on('error', err => {       
          global.console.log(err.message)
});                               
                                  
client.set("foo", 'bar');         
                                  
client.get("foo", function (err, reply) {
        global.console.log(reply.toString())
})

And run node client.js will output :

connected

bar

NOAUTH Authentication required is caused by when redis process command , it found the client is not authenticated so it complained with it.

I guess maybe the redisUrl you give to createClient has some problem, try to debug it or change to my code's way to try. Hopefully you can fix it.

And one more thing: the client.auth(redisPassword) is not necessary because if you set an auth_pass or password option, the redis client will auto send auth command to server before any command.

Community
  • 1
  • 1
GuangshengZuo
  • 4,447
  • 21
  • 27
  • thank you for the advice with auth_pass option. It's useful. As for the issue - I recreated an instance with redis (we use flynn and heroku under the hood of it) an now it works – Enthusiastic Developer Aug 16 '17 at 10:55
  • Hi, I follow your same code and it stills send me the same error. But I realize that it creates the key in my database, but it doesn't allow to run my app. What can I do? Mi error is the following: ReplyError: Ready check failed: NOAUTH Authentication required. at parseError (/home/mauricio/Documents/lisapp/pos_lisa/node_modules/redis-parser/lib/parser.js:193:12) at parseType (/home/mauricio/Documents/lisapp/pos_lisa/node_modules/redis-parser/lib/parser.js:303:14) – maoooricio Oct 24 '18 at 11:52
  • 1
    did you configure your redis server right ? requirepass and protected-mode – GuangshengZuo Oct 25 '18 at 07:51
1

i have used client.connect().then for connection. and option in redis.createClient with url, user, and password. this worked for me update user and password

version

node: v18.16.0 and redis: 4.6.7 (in package.json)

code

import redis from 'redis'
import { log } from 'console'

const client = redis.createClient({
  url: 'redis://localhost/',
  username: 'default',
  password: 'password',
})

client.connect().then(()=> {
  log('Success!')
})

await client.set(id, 'gfg')
log(await client.get(id))
pradeexsu
  • 1,029
  • 1
  • 10
  • 27
0

If you have redis uri saved as string. You need decompose it to object. For ioredis you can use function

export function decomposeRedisUrl(url) {
  const [[, , password, host, port]] = [...(url.matchAll(/redis:\/\/(([^@]*)@)?(.*?):(\d*)/g))];
  return { password, host, port };
}

There are tests for this function:

it("redis url should be decomposed correctly with password", () => {
  expect(decomposeRedisUrl("redis://pass@host.com:9183")).to.eql({
    password: "pass",
    host: "host.com",
    port: "9183",
  });
});

it("redis url should be decomposed correctly without password", () => {
  expect(decomposeRedisUrl("redis://localhost:6379")).to.eql({
    password: undefined,
    host: "localhost",
    port: "6379",
  });
});

and usage

import Redis from "ioredis";

async function getKeysFromRedisUrl(url) {
  const rc = new Redis(decomposeRedisUrl(url));
  const keys = await rc.keys("*");
  rc.disconnect();
  return keys;
}

describe("Redis can connect", () => {
  it("with cloud", async () => {
    expect(await getKeysFromRedisUrl("redis://pass@host.com:9183")).to.be.an("array");
  });
  it("with local redis instance", async () => {
    expect(await getKeysFromRedisUrl("redis://localhost:6379")).to.be.an("array");
  });
});
  • user name is not handled in this function
Daniel
  • 7,684
  • 7
  • 52
  • 76
0

if you're using docker to run Redis, check if your docker-compose has the command: redis-server --requirepass redis

Then check your .env file to make sure you're using it. It was the problem here and I was able to fix it by adding the password at .env file.