node-redis
node-redis copied to clipboard
TypeError when "DENIED Redis is running in protected mode ..."
Description
I am getting a very strange type error everytime I try to use docker compose up to launch any script that connects to redis with the following error message:
redis-test /node_modules/@redis/client/dist/lib/client/commands-queue.js:62
redis-test const { resolve, reject } = __classPrivateFieldGet(this, _RedisCommandsQueue_waitingForReply, "f").shift();
redis-test ^
redis-test
redis-test TypeError: Cannot destructure property 'resolve' of '__classPrivateFieldGet(...).shift(...)' as it is undefined.
redis-test at Object.onReply (/node_modules/@redis/client/dist/lib/client/commands-queue.js:62:25)
redis-test at RESP2Decoder.write (/node_modules/@redis/client/dist/lib/client/RESP2/decoder.js:119:26)
redis-test at RedisCommandsQueue.onReplyChunk (/node_modules/@redis/client/dist/lib/client/commands-queue.js:154:72)
redis-test at RedisSocket.<anonymous> (/node_modules/@redis/client/dist/lib/client/index.js:388:84)
redis-test at RedisSocket.emit (node:events:512:28)
redis-test at Socket.<anonymous> (/node_modules/@redis/client/dist/lib/client/socket.js:202:42)
redis-test at Socket.emit (node:events:512:28)
redis-test at addChunk (node:internal/streams/readable:324:12)
redis-test at readableAddChunk (node:internal/streams/readable:297:9)
redis-test at Readable.push (node:internal/streams/readable:234:10)
redis-test
redis-test Node.js v19.6.1
redis-test exited with code 1
This error does not happen when I connect to redis using the node.js REPL without docker.
This is the docker-compose.yml file I am using to create the redis container:
redis:
image: redis/redis-stack:latest
ports:
- 6379:6379
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
And the code I am using in node.js to connect to redis
import { createClient } from "redis";
(async function () {
const rdb = createClient({
url: 'redis://redis:6379'
});
await rdb.connect();
})();
Node.js Version
19.6.1
Redis Server Version
6.2.8
Node Redis Version
4.6.4
Platform
Linux
Logs
No response
@JohnnyRacer as far as I can tell, this error means that the client got a reply from redis-server, but there are no commands in the queue, which is indeed very strange.
- Are you using the client? executing any commands?
- Does the error throws immediately?
- Can you please add
console.log(reply);beforenode_modules/@redis/client/dist/lib/client/commands-queue.js:62?
If you want, I'll be happy to debug it with you, let me know.. :)
@JohnnyRacer as far as I can tell, this error means that the client got a reply from
redis-server, but there are no commands in the queue, which is indeed very strange.1. Are you using the client? executing any commands? 2. Does the error throws immediately? 3. Can you please add `console.log(reply);` before `node_modules/@redis/client/dist/lib/client/commands-queue.js:62`?If you want, I'll be happy to debug it with you, let me know.. :)
@leibale
- This error occurs before any commands are sent to the client, this happens whenever
await client.connect()is called. - Yes.
- With
console.log(reply)before node_modules/@redis/client/dist/lib/client/commands-queue.js:62.
[ErrorReply: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.]
@leibale
Seems like node-redis does not throw a clear exception when --protected-mode no and a password is not set, I just set this flag in my docker-compose.yml file and now it connects fine with no errors. Not sure if this has any implications for security in production though since I am only accessing redis from my local network, but for testing/development it works fine.
@JohnnyRacer thanks for the information, I'll investigate that. Glad you found a workaround :)
@leibale I ran into this issue as well. The Redis server will send -DENIED or -ERR in some circumstances unconditionally and close the connection: See acceptCommonHandler() in https://github.com/redis/redis/blob/e7a3d3d152c251cc25aed3d89a47a525812e72de/src/networking.c#L1283
I think the library should be able to handle this.
@dtikhonov-iex the library should be able to handle these errors, that's why the issue is still open.. :)
I have found another instance of this happening when using legacyMode: true:
When using pub/subs in legacy mode, be sure to use the v4 functions.
In legacyMode, this will throw the same error as OP.
const heartbeat = redis_client.duplicate();
heartbeat.on('error', err => handleError(err));
heartbeat.connect()
.then(() => {
const listener = (incoming) => {
doListenerThings(incoming)
}
heartbeat.subscribe('key:key:key', listener);
})
.catch(err => handleError(err))
This works fine.
const heartbeat = redis_client.duplicate();
heartbeat.on('error', err => handleError(err));
heartbeat.connect()
.then(() => {
const listener = (incoming) => {
doListenerThings(incoming)
}
//THIS IS THE DIFFERENCE
heartbeat.v4.subscribe('key:key:key', listener);
})
.catch(err => handleError(err))
Adding this here incase more information is wanted:
Running this using the latest version of node 18 seems to resolve the issue, where as the latest LTS seems to cause issue. Recently migrated a program using this package to node 20 and we started finding this issue everytime we tried to start it. After reverting it back to node 18, it was fine again.
Also using redis-stack-server in a docker container
Hi, same issue with nodejs version 18.17.1
TypeError: Cannot destructure property 'resolve' of '__classPrivateFieldGet(...).shift(...)' as it is undefined.
at Object.onReply (/opt/def/def-puresocial-services/node_modules/@redis/client/dist/lib/client/commands-queue.js:62:25)
at RESP2Decoder.write (/opt/def/def-puresocial-services/node_modules/@redis/client/dist/lib/client/RESP2/decoder.js:119:26)
at RedisCommandsQueue.onReplyChunk (/opt/def/def-puresocial-services/node_modules/@redis/client/dist/lib/client/commands-queue.js:154:72)
at RedisSocket.<anonymous> (/opt/def/def-puresocial-services/node_modules/@redis/client/dist/lib/client/index.js:394:84)
at RedisSocket.emit (node:events:514:28)
at Socket.<anonymous> (/opt/def/def-puresocial-services/node_modules/@redis/client/dist/lib/client/socket.js:201:42)
at Socket.emit (node:events:514:28)
at addChunk (node:internal/streams/readable:324:12)
at readableAddChunk (node:internal/streams/readable:297:9)
at Readable.push (node:internal/streams/readable:234:10)
Node.js v18.17.1
Version of redis package is 4.6.10
i got this problem. then i found this only happens when connect to remote redis.
i try redis-cli, got (error) DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients.
so this problem may not be this package's issue, but it is still makes people confuse.
node 18.15.0, "cache-manager-redis-store": "^3.0.1", It happens when using remote redis while local development. After a couple of minutes this error appears: `/Users/user/WebstormProjects/monolytics/node_modules/@redis/client/dist/lib/client/socket.js:194 __classPrivateFieldGet(this, _RedisSocket_instances, "m", _RedisSocket_onSocketError).call(this, new errors_1.SocketClosedUnexpectedlyError()); ^
Error: Socket closed unexpectedly
at TLSSocket.
I have found another instance of this happening when using
legacyMode: true:When using pub/subs in legacy mode, be sure to use the
v4functions.In legacyMode, this will throw the same error as OP.
const heartbeat = redis_client.duplicate(); heartbeat.on('error', err => handleError(err)); heartbeat.connect() .then(() => { const listener = (incoming) => { doListenerThings(incoming) } heartbeat.subscribe('key:key:key', listener); }) .catch(err => handleError(err))This works fine.
const heartbeat = redis_client.duplicate(); heartbeat.on('error', err => handleError(err)); heartbeat.connect() .then(() => { const listener = (incoming) => { doListenerThings(incoming) } //THIS IS THE DIFFERENCE heartbeat.v4.subscribe('key:key:key', listener); }) .catch(err => handleError(err))
Thanks for your response, 🙌 it's work for me ❤️
I have the same issue, using it as described on the socket.io Redis adapter page.
I use the import { createAdapter } from '@socket.io/redis-adapter',
This occurs in my case when the client is waiting for the server to start up for the first time. As the queue returns undefined because there is nothing on the queue yet.
Hacking in a solution into the transpiled javascript code, I've come to the following fix.
In @redis/client/dist/lib/client/commands-queue.js of my node modules directory.
I replace
const { resolve, reject } = __classPrivateFieldGet(this, _RedisCommandsQueue_waitingForReply, "f").shift()
with
const { resolve, reject } = __classPrivateFieldGet(this, _RedisCommandsQueue_waitingForReply, "f").shift() || {resolve:()=>{}, reject:()=>{}};
and this solves my issue.
Again this is a hack. The real issue stems from the non-null assertion operator found here in the source code. https://github.com/redis/node-redis/blob/d5355d43275fedf1b2afc4db8a926f72b05f79c5/packages/client/lib/client/commands-queue.ts#L90
UPDATE
Looks like this PR has a fix for the issue #2549
Had to hack this also. Would be great to have lib support.