Há algum tempo, um dos meus servidores de testes ficou exatamente nesse ponto: precisei resolver manualmente conflitos de pacotes do apt “na mão”. Eu tinha um sistema Debian que, por anos, nunca havia sido completamente atualizado, ficando preso em algum lugar entre o Stretch e o Bookworm – com uma mistura caótica de versões de pacotes que, na teoria, nunca deveriam coexistir. apt se recusava a fazer qualquer coisa e dpkg --configure -a falhava sempre no mesmo ponto. No final, nenhum comando padrão ajudava. Tive que descompactar os pacotes .deb manualmente com Python, só para entender o que o gerenciador de pacotes queria instalar de verdade e o que já estava presente no sistema e em qual versão.
É justamente esse cenário – uma mudança de versão (release) não concluída corretamente, que te persegue meses ou anos depois na forma de erros enigmáticos do apt – que é o clássico sobre o qual esse artigo trata.
Você alterou no /etc/apt/sources.list de stretch para bullseye ou de bullseye para bookworm, apt update ainda rodou – mas no apt upgrade ou apt full-upgrade tudo falha com mensagens de erro obscuras. Esse problema é muito mais comum do que se imagina, especialmente em servidores que ficam rodando por anos e vão “crescendo” ao longo de várias gerações do Debian, em vez de serem reinstalados do zero.
Por que isso acontece
Uma troca de release do Debian não é apenas subir a versão. Entre duas gerações do Debian, algumas coisas mudam:
- Nomes e divisões de pacotes – um pacote é dividido em dois ou dois pacotes são fundidos em um
- Versões de dependências – um pacote agora exige uma versão da libc que ainda não está instalada
- Formatos de arquivos de configuração –
dpkgpergunta durante o upgrade se um arquivo de configuração alterado deve ser sobrescrito e, em processos não-interativos (ex.: via SSH com-y), pode travar exatamente aí - Resquícios de repositórios antigos – se ainda há linhas do release antigo em
sources.list(erro clássico: só alterar a linha principal, mas esquecer-updatesou-security), oaptmistura pacotes de duas gerações diferentes
O resultado normalmente se enquadra em uma de três classes de erro:
trying to overwrite '/usr/lib/xyz', which is also in package abcThe following packages have unmet dependenciesdpkg: error processing package xyz (--configure): dependency problems - leaving unconfigured
Passo 1: Diagnóstico antes do pânico
Antes de instalar ou remover qualquer coisa, obtenha uma visão geral limpa:
apt list --upgradable 2>/dev/null apt-cache policy | head -20 cat /etc/apt/sources.list /etc/apt/sources.list.d/*.list
Confira cuidadosamente aqui se todas as linhas (main, updates, security, talvez backports) apontam de forma consistente para o mesmo release. Essa é a causa mais comum e pode ser resolvida em 5 minutos – antes que você se aprofunde em erros mais complexos, que na verdade são só sintomas desse erro inicial.
Passo 2: Colocando o dpkg em um estado limpo
Se o dpkg trava no meio de uma configuração, tente primeiro:
sudo dpkg --configure -a
Esse comando tenta concluir a configuração de todos os pacotes semi-instalados. Se aparecer um erro para um pacote específico, anote o nome do pacote – esse é seu ponto de partida para investigação.
Passo 3: Deixe o apt tentar reparar dependências
sudo apt --fix-broken install
Esse é o comando que resolve na maioria dos casos: apt procura sozinho uma combinação de instalar/remover que torne a cadeia de dependências consistente novamente. Importante: Antes de confirmar, leia a lista de mudanças propostas – às vezes o apt sugere a remoção de algum pacote que você precisa, simplesmente porque ainda não existe uma versão compatível.
Passo 4: O caso “trying to overwrite”
Essa mensagem de erro significa: dois pacotes querem instalar o mesmo arquivo, pois a estrutura dos pacotes foi alterada entre os releases (por ex., um pacote foi dividido em paket-common e paket-bin). A solução rápida, porém perigosa, seria dpkg -i --force-overwrite. Não faça isso como primeira opção. Primeiro, verifique se se trata de um problema de divisão conhecido:
dpkg -S /caminho/do/arquivo_com_conflito apt-cache policy <pacote-afetado>
Geralmente basta remover limpo o pacote mais antigo e agora obsoleto (apt remove <pacote-antigo>) antes de instalar o novo, em vez de forçar a instalação. Instalações forçadas podem deixar o banco de dados do dpkg inconsistente, e esse problema pode ressurgir semanas depois.
Passo 5: Quando nada mais funciona – análise manual do .deb
Em casos persistentes, onde apt e dpkg se travam mutuamente (por exemplo, com uma mistura de duas versões intermediárias já não suportadas), pode ser necessário extrair manualmente o pacote problemático e inspecioná-lo, em vez de confiar no gerenciador de pacotes:
apt-get download <nome-do-pacote> dpkg-deb -R <nome-do-pacote>*.deb /tmp/conteudo-pacote
Assim, você vê exatamente quais arquivos o pacote quer instalar e pode checar manualmente quais deles já existem (talvez com outro nome) no sistema. Esse é o último recurso quando o caminho padrão com apt --fix-broken install já não resolve – por exemplo, quando o banco de dados dos pacotes está tão corrompido por causa da mistura de duas ou três gerações do Debian, que apt já não consegue calcular uma solução válida.
Prevenção para a próxima vez
- Sempre faça a mudança de release com
do-release-upgrade(no Ubuntu) ou pelo guia oficial de upgrade do Debian, não só editando manualmente osources.liste depois rodandodist-upgrade - Sempre faça um snapshot/backup do sistema antes de qualquer upgrade (snapshot LVM, snapshot de VM, ou pelo menos
dpkg --get-selections > pacotes-backup.txt) - Reescreva o
sources.listinteiro a cada troca de release, em vez de editar linha por linha – assim evita a “linha -security esquecida”
Conclusão
A maioria dos casos em que o “apt quebra após troca de release” não são danos reais ao sistema, mas estados intermediários inconsistentes que podem ser resolvidos com dpkg --configure -a seguido de apt --fix-broken install em mais de 80% das vezes. Só nos casos mais teimosos vale a análise manual do .deb – mas aí, pelo menos, você tem controle total sobre o que está acontecendo, em vez de arriscar tudo com --force-overwrite.
No meu caso do servidor de e-mail, no final, essa foi a única maneira de restaurar o sistema funcional: extrair pacote por pacote manualmente, comparar, decidir o que fica e o que deve ser removido – em vez de confiar cegamente no gerenciador de pacotes, que, naquele estado intermediário quebrado, simplesmente não conseguia mais encontrar uma solução válida. A lição não foi só técnica, mas principalmente organizacional: uma troca de release feita “de qualquer jeito” quase sempre cobra sua conta meses depois – e aí é problemão.