Erro 1071 MySQL: Specified key was too long, como resolver
Entenda o erro 1071 do MySQL, os limites de 767 e 3072 bytes do InnoDB, a conta com utf8mb4 e as soluções: índice de prefixo, coluna menor e ROW_FORMAT.
Por Redação Eleven Host · @robson.direitodigital · 1 de novembro de 2026 · 9 min de leitura

Capa da Redação Eleven Host para o guia: Erro 1071 MySQL: Specified key was too long, como resolver Arte: Eleven Host
O erro 1071 MySQL, Specified key was too long, aparece quando o índice pedido passa do tamanho máximo de chave que o MySQL aceita. Com utf8mb4, cada caractere pode ocupar até 4 bytes, e uma coluna longa indexada estoura o limite.
Este guia mostra como ler a mensagem e por que o limite existe, com a conta dos bytes. Depois, como ver o formato de linha e o conjunto de caracteres da tabela e três soluções: índice de prefixo, coluna menor e ROW_FORMAT=DYNAMIC. Os fatos vêm do manual do MySQL 8.0 e da referência de erros do 8.0 e do 8.4; os nomes dos exemplos são fictícios.
O que a mensagem diz
Na referência de erros do servidor do MySQL, o erro 1071 tem o símbolo ER_TOO_LONG_KEY, o SQLSTATE 42000 e esta mensagem:
Specified key was too long; max key length is %d bytes
O %d é o espaço onde o servidor coloca o tamanho máximo em bytes. Um exemplo de como a mensagem pode aparecer, só para ilustrar (o número depende da sua tabela):
Specified key was too long; max key length is 3072 bytes
Em português: "a chave especificada era longa demais". O número no fim é o limite que o servidor aplicou àquela tabela, e ele muda conforme o formato de linha, como mostra a próxima seção.
O erro 1071 não diz que o dado está errado. Ele diz que o índice pedido ocupa mais bytes do que o InnoDB aceita numa chave.
Por que acontece: os limites do InnoDB
O manual do MySQL, na página de limites do InnoDB, traz duas regras que dependem do formato de linha da tabela:
- Para tabelas InnoDB com formato de linha
DYNAMICouCOMPRESSED, o limite do prefixo da chave do índice é de 3072 bytes. - Para tabelas InnoDB com formato
REDUNDANTouCOMPACT, o limite é de 767 bytes.
A mesma página diz que tentar usar um prefixo de chave acima do limite devolve um erro, e que os limites do prefixo de índice valem também para chaves de coluna inteira. Indexar a coluna completa, portanto, não escapa da regra.
A página ainda traz um caso em que o limite cai: se o tamanho de página do InnoDB for reduzido para 8KB ou 4KB na criação da instância, o tamanho máximo da chave cai na mesma proporção, para 1536 bytes com páginas de 8KB e 768 bytes com páginas de 4KB.
A conta dos bytes com utf8mb4
O conjunto de caracteres utf8mb4, segundo o manual, exige no máximo quatro bytes por caractere de vários bytes. O limite é em bytes, e a coluna é declarada em caracteres. Então, no pior caso com utf8mb4, a conta é o número de caracteres vezes 4.
O manual dá o exemplo do limite de 767 bytes: você pode bater nele com um índice de prefixo de mais de 191 caracteres numa coluna TEXT ou VARCHAR, supondo utf8mb4 e o máximo de 4 bytes por caractere. A conta fecha assim:
- 191 caracteres x 4 bytes = 764 bytes, que cabe em 767.
- 192 caracteres x 4 bytes = 768 bytes, que passa de 767.
Com DYNAMIC ou COMPRESSED, o teto de 3072 bytes permite indexar até 768 caracteres de uma coluna utf8mb4 (3072 dividido por 4). A página de conversão de utf8mb3 para utf8mb4 confirma os números: 255 ou 191 caracteres com o limite de 767 bytes, e 1024 ou 768 caracteres com o limite de 3072 bytes, para utf8mb3 ou utf8mb4, respectivamente.
Um exemplo para fixar: uma coluna VARCHAR(1000) em utf8mb4 pode chegar a 4000 bytes, mais do que os 3072 do DYNAMIC. Indexar essa coluna inteira pode dar o erro 1071 mesmo no formato DYNAMIC.
Quer conhecer o banco de dados na nuvem 11SQL? 11SQL Mini a partir de R$ 9,90/mês; confira na loja o que cada plano inclui. Conhecer o 11SQL
Ver o formato de linha e o conjunto de caracteres
Antes de escolher a solução, descubra em qual cenário você está. Para o formato de linha, o manual mostra duas formas. A primeira é o SHOW TABLE STATUS:
SHOW TABLE STATUS IN minha_base\G
A segunda é consultar a tabela INNODB_TABLES do Information Schema:
SELECT NAME, ROW_FORMAT FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME='minha_base/minha_tabela';
Segundo o manual, o formato padrão das tabelas InnoDB é definido pela variável innodb_default_row_format, cujo valor padrão é DYNAMIC. Esse padrão vale quando a opção ROW_FORMAT não é definida de forma explícita. Se a sua tabela mostra COMPACT ou REDUNDANT, o teto é de 767 bytes, e é aí que o 191 aparece.
Para o conjunto de caracteres, confira como a coluna foi definida na tabela. Se for utf8mb4, use 4 bytes por caractere na conta. Se um tutorial falar em 255 caracteres, o número corresponde ao utf8mb3 com o limite de 767 bytes, como na página de conversão do manual (o utf8mb3 usa no máximo três bytes por caractere). O guia Erro 1366 MySQL: Incorrect string value, como resolver trata de outro erro ligado ao conjunto de caracteres.
Solução 1: índice de prefixo
Uma saída é indexar só o começo da coluna. O manual explica que, em colunas de texto, o índice pode usar apenas a parte inicial dos valores, com a sintaxe col_name(length). Exemplo literal da página:
CREATE INDEX part_of_name ON customer (name(10));
Aplicado ao caso de um e-mail em utf8mb4, com o limite de 767 bytes:
CREATE INDEX idx_email ON minha_tabela (email(191));
Um ponto que causa surpresa: o manual diz que o comprimento do prefixo é interpretado como número de caracteres para tipos de texto não binários (CHAR, VARCHAR, TEXT) e como número de bytes para tipos binários (BINARY, VARBINARY, BLOB). Por isso o 191 do exemplo é em caracteres.
Duas regras do mesmo trecho do manual valem para este caso. Primeiro, colunas BLOB e TEXT exigem prefixo. Segundo, quando o prefixo é grande demais e o índice não é único, ou ocorre um erro (com o modo SQL estrito ligado) ou o comprimento é reduzido e aparece um aviso (sem o modo estrito). Para um índice único, o erro ocorre independentemente do modo SQL, porque reduzir o comprimento poderia permitir entradas repetidas. Se o índice era UNIQUE, pense no que o prefixo significa para a regra de unicidade antes de usar esta solução. Se uma gravação com valor repetido falhar depois, o guia Erro 1062 MySQL: Duplicate entry, como resolver ajuda a ler a mensagem.
Solução 2: reduzir o VARCHAR indexado
Se a coluna não precisa de tantos caracteres, a página de conversão do manual indica este caminho: reduzir o tamanho definido das colunas ou dos índices. Um e-mail declarado como VARCHAR(500) pode caber em um tamanho menor, e a conta passa a fechar sem prefixo.
Antes de mudar a coluna, faça backup e confira qual é o maior valor guardado nela, para não cortar dados. O manual mostra o formato de um ALTER TABLE com MODIFY na página de conversão de conjunto de caracteres; use-o como modelo de sintaxe e troque pelos seus nomes e tipos. Se o comando der erro de sintaxe, o guia sobre o erro 1064 MySQL (erro de sintaxe SQL) mostra como ler a mensagem.
A mesma página lembra que a outra alternativa é continuar em utf8mb3 em vez de utf8mb4. Ela tem um custo: segundo o manual, o utf8mb3 suporta só caracteres do plano básico (BMP), e o utf8mb4 também suporta os caracteres suplementares. Considere isso antes de escolher esse caminho.
Solução 3: ROW_FORMAT=DYNAMIC
Se a tabela está em COMPACT ou REDUNDANT, mudar o formato de linha para DYNAMIC sobe o teto de 767 para 3072 bytes. O manual diz que o DYNAMIC suporta prefixos de chave de até 3072 bytes e que o formato de uma tabela pode ser definido de forma explícita com a opção ROW_FORMAT em um CREATE TABLE ou ALTER TABLE. O exemplo literal da página:
CREATE TABLE t1 (c1 INT) ROW_FORMAT=DYNAMIC;
Para uma tabela que já existe, por exemplo, um comando montado a partir dessa opção documentada seria este (não é um comando copiado da documentação):
ALTER TABLE minha_tabela ROW_FORMAT=DYNAMIC;
Faça backup antes. O comando altera a estrutura da tabela, e não há como prometer quanto tempo ele leva numa tabela grande. Depois, confira o resultado com a consulta ao INNODB_TABLES da seção anterior e tente criar o índice de novo.
innodb_large_prefix: removido no MySQL 8.0
Em tutoriais antigos aparece a variável innodb_large_prefix, junto com as de formato de arquivo do InnoDB. No MySQL 8.0 isso mudou: a lista de recursos removidos do manual inclui as variáveis innodb_file_format, innodb_file_format_check, innodb_file_format_max e innodb_large_prefix. O manual explica que essas variáveis eram necessárias para criar tabelas compatíveis com versões antigas do InnoDB.
Na prática, no 8.0 não há o que ligar: se um tutorial mandar ajustar innodb_large_prefix, pule esse passo e use uma das três soluções acima.
Checklist do erro 1071
- Leia o número da mensagem: é o limite em bytes que o servidor aplicou.
- Veja o formato de linha da tabela (
SHOW TABLE STATUSouINNODB_TABLES): 3072 bytes paraDYNAMICeCOMPRESSED, 767 paraREDUNDANTeCOMPACT. - Faça a conta: caracteres x 4 bytes com utf8mb4 (191 x 4 = 764).
- Primeira saída: índice de prefixo, como
email(191), lembrando que o valor é em caracteres. - Segunda: reduzir o
VARCHARindexado, depois de conferir o maior valor guardado. - Terceira:
ROW_FORMAT=DYNAMIC, com backup antes. - Não ligue
innodb_large_prefix: ela foi removida no 8.0. - Em índice
UNIQUE, pense na regra de unicidade antes de usar prefixo.
Está escolhendo uma VPS? VPS a partir de R$ 17,00/mês no Plano Bronze; confira na loja o que cada plano inclui. Ver os planos de VPS
Perguntas frequentes
O que significa o erro 1071 no MySQL?
Significa "Specified key was too long": o índice pedido passa do tamanho máximo de chave. O símbolo é ER_TOO_LONG_KEY e o SQLSTATE é 42000.
Por que o número 191 aparece tanto?
Porque, no limite de 767 bytes e com utf8mb4 (até 4 bytes por caractere), 191 caracteres ocupam 764 bytes. Com 192, a conta passa de 767.
Qual o limite de uma chave no InnoDB?
Segundo o manual do MySQL 8.0, 3072 bytes para os formatos DYNAMIC e COMPRESSED, e 767 bytes para REDUNDANT e COMPACT.
Devo ligar innodb_large_prefix?
No MySQL 8.0, não: a variável foi removida. Use índice de prefixo, uma coluna menor ou o formato DYNAMIC.
O prefixo do índice é em bytes ou em caracteres?
Em caracteres para CHAR, VARCHAR e TEXT, e em bytes para BINARY, VARBINARY e BLOB.