top of page

Access denied (authentication failure) no MySQL: causas reais e roteiro de diagnóstico


O sintoma

ERROR 1045 (28000): Access denied for user 'app_user'@'10.0.x.x' (using password: YES) é um dos erros mais reportados no MySQL, e também um dos mais mal diagnosticados. A mensagem é genérica por natureza: ela dispara para credencial incorreta, para usuário que não existe para aquele host específico e para incompatibilidade de plugin de autenticação — três causas com correções completamente diferentes. Tratar todos os casos como "senha errada" e sair trocando senha é o motivo pelo qual esse erro volta a aparecer dias depois.

Este post é um roteiro de diagnóstico para ir da mensagem genérica até a causa real, sem achismo.


Diagnóstico passo a passo

1. Confirme se o usuário existe para aquele host exato

O MySQL não trata user como uma entidade única — a chave real é o par user@host. É comum existir app_user@10.0.1.5 mas a aplicação estar conectando de 10.0.1.6, ou existir app_user@localhost quando a conexão chega via TCP/IP e precisaria de app_user@10.0.% ou app_user@%.

SELECT user, host, plugin, account_locked
FROM mysql.user
WHERE user = 'app_user';

Se a linha esperada não aparecer com o host correto, a causa já está identificada: falta de entrada para aquele host, não senha incorreta.


2. Lembre-se de como o MySQL resolve qual linha usar

Quando existe mais de uma linha para o mesmo usuário com hosts diferentes (por exemplo app_user@10.0.1.5 e app_user@%), o servidor ordena as linhas com os valores de Host mais específicos primeiro e usa a primeira que casar com a conexão — não necessariamente a que você "esperava" que fosse usada. Um detalhe frequentemente esquecido: uma linha de usuário anônimo (User em branco) com host mais específico pode ser escolhida antes de uma linha nomeada com host menos específico. Isso é comportamento documentado da Oracle para a fase de "Connection Verification" do controle de acesso, não bug.


3. Verifique incompatibilidade de plugin de autenticação

Desde o MySQL 8.0.4, o plugin de autenticação padrão passou de mysql_native_password para caching_sha2_password. A partir do MySQL 8.4, mysql_native_password está deprecated, ou seja, troque o quanto antes de sua aplicação. Esse é hoje um dos motivos mais comuns de Access denied em ambientes que foram migrados ou tiveram o servidor atualizado: o driver/cliente da aplicação (versões antigas de conectores Java, PHP, Python) não suporta caching_sha2_password e a autenticação falha mesmo com a senha certa.

SELECT user, host, plugin
FROM mysql.user
WHERE user = 'app_user';

Se o plugin estiver como caching_sha2_password e o cliente for antigo ou não suportar o protocolo, a solução é recriar a credencial com o plugin compatível:

ALTER USER 'app_user'@'10.0.%' IDENTIFIED WITH mysql_native_password BY 'senha_atual';

(Avalie o trade-off de segurança antes de reverter para mysql_native_password — é uma correção de compatibilidade, não a opção recomendada por padrão pela própria Oracle.)


4. Confira o error log para a mensagem completa

O ERROR 1045 que chega ao cliente é resumido. O log de erros do servidor registra mais contexto sobre tentativas de conexão rejeitadas quando log_error_verbosity está no valor padrão (3):

SHOW VARIABLES LIKE 'log_error_verbosity';

Com verbosity 3 (padrão), o servidor já registra conexões abortadas e erros de acesso negado no log de erros — vale checar esse arquivo antes de qualquer alteração de configuração, em vez de assumir que é preciso mudar o parâmetro.


5. Confirme os privilégios, não só a autenticação

Um erro comum é resolver a autenticação e continuar vendo comportamento de acesso negado em operações específicas — nesse caso o problema já não é mais o 1045, e sim falta de GRANT:

SHOW GRANTS FOR 'app_user'@'10.0.%';

Solução aplicada

Combinando os passos acima, a correção cai em um destes três cenários. Se o host estava errado, crie a entrada correta com CREATE USER 'app_user'@'10.0.%' IDENTIFIED BY '...' e replique os GRANT da entrada existente. Se o plugin era incompatível, use ALTER USER para ajustar o plugin de autenticação, ou atualize o driver/conector cliente para suportar caching_sha2_password. E se a senha estava mesmo incorreta, redefina com ALTER USER 'app_user'@'10.0.%' IDENTIFIED BY 'nova_senha';.

Um ponto técnico que gera confusão: FLUSH PRIVILEGES não é necessário após CREATE USER, ALTER USER, GRANT ou REVOKE — esses comandos já atualizam as tabelas de privilégio em memória. FLUSH PRIVILEGES só é exigido quando as tabelas de grant (mysql.user, mysql.db etc.) são alteradas diretamente via INSERT/UPDATE/DELETE, o que deve ser evitado.


Quando o acesso está totalmente bloqueado

Se o usuário afetado for o próprio root e não houver outra conta com privilégio de administração disponível, a recuperação documentada pela Oracle é subir a instância com --skip-grant-tables (que ativa automaticamente --skip-networking, bloqueando conexões remotas por segurança), conectar localmente sem senha, redefinir a credencial com ALTER USER e reiniciar o serviço normalmente. É um procedimento que exige acesso ao host e parada do serviço — não é algo a se fazer em produção sem janela de manutenção.


Validação

Depois da correção, valide a partir do mesmo host/rede de onde a aplicação se conecta de fato — não apenas do host do DBA:

SELECT user, host, plugin FROM mysql.user WHERE user = 'app_user';
SHOW GRANTS FOR 'app_user'@'10.0.%';

E teste a conexão real com o cliente/driver usado em produção, não apenas com o mysql CLI — como visto no passo 3, o cliente da aplicação pode ter uma limitação que o CLI não tem.


Nota para MySQL gerenciado (RDS/Aurora)

Em RDS/Aurora, o mesmo roteiro de mysql.user, host matching e plugin de autenticação se aplica normalmente — mas a recuperação de senha do usuário master não passa por --skip-grant-tables (o acesso ao host não existe em serviço gerenciado). O fluxo exato de reset do master user deve ser via console/CLI da AWS, pois pode variar entre engine e versão — confirme na documentação oficial antes de aplicar em produção.

Esse tipo de erro custa tempo de diagnóstico quando tratado como "só trocar a senha". Ter o roteiro (host, plugin, log, grants) reduz o vaivém entre tentativa e erro — e evita reabrir o mesmo chamado na semana seguinte.

 
 
 

Posts recentes

Ver tudo

Comentários


© 2026 por Siltech Consult

  • LinkedIn
bottom of page