Publicado el Actualizado el

Cómo solucionar el error "Specified key was too long" en Laravel (3 soluciones)

Foto de Marco Orta | 2 min de lectura
Mensaje de error de MySQL "Specified key was too long" en la consola de Laravel durante migraciones
Tabla de Contenidos

    ⚙️ Nota 2026: si estás usando MySQL 8 o MariaDB 10.5+ con un Laravel 9 o superior, ya no deberías ver este error en proyectos nuevos: el charset por defecto es utf8mb4 con innodb_default_row_format=DYNAMIC, y los índices ya soportan hasta 3072 bytes. El artículo sigue siendo útil si trabajas con bases de datos heredadas, servidores antiguos o hostings compartidos que aún corren MySQL 5.6/5.7 o MariaDB 10.1.

    En cuántas ocasiones has instalado un nuevo proyecto en Laravel y al momento de correr las migraciones te has encontrado con un error en tu consola:

    [Illuminate\Database\QueryException]
    SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email))
    
    [PDOException]
    SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
    

    Podemos solucionarlo de 3 formas:

    Solución 1

    Si utilizas MySQL anterior a la 5.7.7 o MariaDB anterior a la 10.2.2, simplemente actualiza a la versión estable más reciente y no volverás a tener este problema.

    Solución 2

    Si no puedes actualizar el servidor pero sí administrarlo, ataca la causa: el formato de fila de InnoDB. Las tablas con formato COMPACT o REDUNDANT (el formato de archivo Antelope) solo admiten claves de índice de 767 bytes; con DYNAMIC o COMPRESSED (formato Barracuda) y innodb_large_prefix activado, el límite sube a 3072 bytes. En MySQL 5.7 eso ya viene activado por defecto; en MySQL 5.6 tienes que encenderlo tú en my.cnf y reiniciar:

    [mysqld]
    innodb_file_format = Barracuda
    innodb_file_per_table = 1
    innodb_large_prefix = 1
    

    Y las tablas tienen que crearse con ROW_FORMAT=DYNAMIC. Laravel concatena el valor de engine de config/database.php al CREATE TABLE, así que puedes forzarlo desde ahí:

    'mysql' => [
        ...
        'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
    ]
    

    Ojo: poner solo 'engine' => 'InnoDB' no arregla nada. InnoDB es el motor por defecto desde MySQL 5.5; el límite de 767 bytes depende del formato de fila, no del motor.

    Solución 3

    Si no puedes tocar la configuración del servidor (un hosting compartido, por ejemplo), agrega la siguiente línea al archivo app/Providers/AppServiceProvider.php

    use Illuminate\Support\Facades\Schema;
    
    public function boot()
    {
        Schema::defaultStringLength(191);
    }
    

    ¿Por qué ocurre este error?

    Desde la versión 5.4 de Laravel se realizó un cambio en el conjunto de caracteres predeterminado de la base de datos, y ahora es utf8mb4, que incluye soporte para almacenar emojis. En utf8mb4 cada carácter puede ocupar hasta 4 bytes, así que un VARCHAR(255) indexado, como el email único de la tabla users, necesita hasta 1020 bytes y rebasa el límite de 767. Con 191 caracteres (764 bytes) cabe, y por eso funciona la Solución 3. Solo afecta a servidores donde ese límite sigue activo: MySQL anterior a la 5.7.7, MariaDB anterior a la 10.2.2, o tablas que se quedaron en formato COMPACT.

    ¿Te sirvió? Compártelo

    ¿Te sirvió? Recibe la próxima por correo

    Una vez por semana: qué se rompe al actualizar, IA para desarrolladores y lo que estoy construyendo, con fuentes. Sin spam.

    Al suscribirte aceptas nuestro aviso de privacidad.

    Buscar

    Etiquetas

    IA Migración PHP Laravel JavaScript Tutorial Desarrollo Web Seguridad Upgrade Buenas Prácticas OpenAI SEO Backend Claude Laravel 13