Solución: secretOrPrivateKey must have a value en JWT / jsonwebtoken
jsonwebtoken lanza este error cuando la clave secreta es undefined. Casi siempre por una variable de entorno no cargada. Cómo diagnosticarlo y proteger la generación de tokens.
¿Por qué ocurre?
La función `jwt.sign()` o `jwt.verify()` recibe `undefined` como clave secreta porque la variable de entorno `JWT_SECRET` (o como la hayas llamado) no está definida en el entorno donde corre el código. Ocurre al olvidar añadir la variable en producción, al no tener el .env cargado, o al escribir mal el nombre de la variable.
Solución paso a paso
Diagnóstico rápido:
console.log('JWT_SECRET:', process.env.JWT_SECRET);
// Si imprime "undefined", ese es el problema
Caso 1 — Falta cargar dotenv:
// ❌ dotenv no está cargado antes de usarlo
const jwt = require('jsonwebtoken');
jwt.sign(payload, process.env.JWT_SECRET); // undefined// ✅ Carga dotenv al principio del archivo de entrada (server.js, index.js)
require('dotenv').config(); // ← debe ser la primera línea
const jwt = require('jsonwebtoken');
jwt.sign(payload, process.env.JWT_SECRET); // ✅
# Instala dotenv si no lo tienes
npm install dotenv
Caso 2 — Variable no definida en producción:
# Vercel → Settings → Environment Variables
# Netlify → Site settings → Environment variables
# Railway / Render → Variables tab# En el servidor propio:
export JWT_SECRET="tu-clave-secreta-larga-y-aleatoria"
# o en el archivo .env del servidor (nunca subas este archivo a git)
Caso 3 — Nombre de variable incorrecto:
// .env
JWT_SECRET=mi-secreto// ❌ Nombre diferente
jwt.sign(payload, process.env.JWT_SECRETO); // undefined — typo
// ✅ Nombre exactamente igual que en .env
jwt.sign(payload, process.env.JWT_SECRET);
Validación al arrancar la aplicación:
// ✅ Valida las variables críticas al inicio — falla rápido y claro
const requiredEnvVars = ['JWT_SECRET', 'DATABASE_URL'];for (const key of requiredEnvVars) {
if (!process.env[key]) {
throw new Error(Variable de entorno requerida no definida: ${key});
}
}
// Uso seguro con valor tipado (TypeScript)
const JWT_SECRET = process.env.JWT_SECRET as string;
Generar una clave secreta segura:
# Node.js — genera un string aleatorio de 64 bytes en base64
node -e "console.log(require('crypto').randomBytes(64).toString('base64'))"
Cómo evitarlo en el futuro
Valida todas las variables de entorno críticas al arrancar la aplicación. Usa una librería como `zod` o `envalid` para validar el .env completo en el startup. Nunca hagas fallback a strings vacíos o valores por defecto en variables de seguridad.
¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:
Generador de Prompts