From 07bec5aa6db9ddd3fe231c51c54238df4947d287 Mon Sep 17 00:00:00 2001 From: Dom Rettig Date: Thu, 11 Jun 2026 21:20:34 -0700 Subject: [PATCH] Set redis user and pw in no-cluster mode (#747) * set redis user and pw in no-cluster mode * Apply redis auth to cluster mode via shared helper The single-node fix only covered the non-cluster path; the cluster branch still called safeGetEnvVar for REDIS_USER/REDIS_PASSWORD, which throws at boot when they are unset and always sent an empty username. Extract a redisAuthOptions() helper so both paths send credentials only when REDIS_PASSWORD is set and omit the username for the default user. --------- Co-authored-by: Juan S. Mrad --- server/iocContainer/index.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/server/iocContainer/index.ts b/server/iocContainer/index.ts index 739571a..04f009a 100644 --- a/server/iocContainer/index.ts +++ b/server/iocContainer/index.ts @@ -579,6 +579,22 @@ export default async function getBottle() { }), ); + // AUTH-enabled Redis (e.g. ElastiCache with an auth token) rejects every + // command with NOAUTH unless credentials are sent, which leaves ioredis stuck + // before "ready" and parks commands in the offline queue forever. Local dev + // Redis has no password, so only pass credentials when REDIS_PASSWORD is set; + // REDIS_USER may be set-but-empty, which means the default user. Shared by the + // cluster and single-node paths so both authenticate identically. + const redisAuthOptions = (): { username?: string; password?: string } => + process.env.REDIS_PASSWORD + ? { + ...(process.env.REDIS_USER + ? { username: process.env.REDIS_USER } + : {}), + password: process.env.REDIS_PASSWORD, + } + : {}; + const makeRedis = ( extraOptions: { enableOfflineQueue?: boolean } = {}, ): IORedis.Redis | Cluster => @@ -599,8 +615,7 @@ export default async function getBottle() { // Required by BullMQ: its workers use blocking Redis commands // that would otherwise be misinterpreted as timed-out requests. maxRetriesPerRequest: null, - username: safeGetEnvVar('REDIS_USER'), - password: safeGetEnvVar('REDIS_PASSWORD'), + ...redisAuthOptions(), ...extraOptions, }, }, @@ -611,6 +626,7 @@ export default async function getBottle() { maxRetriesPerRequest: null, port: parseInt(process.env.REDIS_PORT ?? '6379'), host: safeGetEnvVar('REDIS_HOST'), + ...redisAuthOptions(), ...(isEnvTrue('REDIS_TLS') ? { tls: { servername: safeGetEnvVar('REDIS_HOST') } } : {}), -- 2.51.2