ITMS-90034: corrigir “Missing or invalid signature”
Por Mehdi Azizi
Publicado em , 8 min
ITMS-90034: seu build não está assinado com um certificado de distribuição válido. Leia a assinatura com codesign e refaça um build store com o EAS.
ITMS-90034 aparece quando você envia seu build para o App Store Connect. Ele diz que seu app, ou um dos componentes dele, não está assinado com um certificado de envio da Apple, ou seja, um certificado de distribuição válido. A correção: descobrir qual bundle está mal assinado e por quê, e depois refazer um build assinado para a App Store.
Este guia fica focado no erro. Se as palavras certificado e perfil ainda estão confusas para você, leia antes certificado de desenvolvedor iOS e provisioning profile. Aqui você vai encontrar a mensagem a ler, uma árvore de decisão, os comandos que inspecionam seu IPA e a correção com as credenciais gerenciadas pelo EAS. Para a parte do EAS, eu li o código do EAS CLI 24.10.0 que escolhe o certificado.
O que significa o erro ITMS-90034?
Esta é a forma clássica dele, com nomes de exemplo:
ITMS-90034: Missing or invalid signature. The bundle 'com.example.myapp' at bundle path 'Payload/MyApp.app' is not signed using an Apple submission certificate.
Em 2026, no fórum da Apple, ele também aparece na forma "Validation failed (409) Missing or invalid signature", seguido do mesmo texto e de "(ID: 90034)".
O "certificado de envio" (submission certificate) é o certificado de distribuição. A ajuda da Apple sobre certificados diz isso: os certificados de desenvolvimento servem para rodar seu app nos seus aparelhos, os de distribuição servem para distribuí-lo ou enviá-lo ao App Store Connect.
Leia o caminho citado: ele aponta o bundle com problema. Payload/MyApp.app se refere ao próprio app. Um caminho que termina em .appex se refere a uma extensão, como um widget. Um caminho em .framework se refere a uma biblioteca embutida.
Não é uma recusa de um reviewer. A validação acontece no envio ou durante o processamento do build, antes do TestFlight: esse build nunca vai chegar aos seus testadores.
A árvore de decisão: da mensagem à correção
Cada linha corresponde a uma pista que você lê na mensagem, nos comandos da próxima seção ou nos logs do EAS. Siga a ordem: a primeira que bater indica o seu caminho.
| O que você observa | Causa provável | Correção |
|---|---|---|
Caminho em .appex | Extensão mal assinada | Declarar a extensão |
Signature=adhoc | Build não assinado | Build com perfil store |
Apple Development | Build de desenvolvimento | Build com perfil store |
ProvisionedDevices lido | Build interno (ad hoc) | Build com perfil store |
sealed resource | IPA alterado depois | Refazer o build |
| EAS: "no longer valid" | Certificado revogado | Novo certificado |
| Tudo válido | Problema do lado da Apple | Reenviar, depois reportar |
Inspecionar seu IPA em quatro comandos
Baixe o IPA na página do build no expo.dev e abra um terminal no seu Mac.
1. Quem assinou o app?
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
O codesign escreve na saída de erro, por isso o 2>&1. Segundo a nota técnica TN3161 da Apple, cada linha Authority é um elo da cadeia de confiança. A primeira deve começar com Apple Distribution: ou iPhone Distribution:, seguida do nome do seu time. O segundo rótulo é o do antigo tipo iOS Distribution: pelo código dele, o EAS CLI 24.10.0 ainda cria certificados desse tipo. Se você lê Apple Development:, é um build de desenvolvimento. Se você lê Signature=adhoc sem nenhuma linha Authority, o binário não está assinado por nenhum certificado.
2. O app foi alterado depois da assinatura?
codesign --verify --deep --strict -vv ipa/Payload/*.app
Você quer ler valid on disk e depois satisfies its Designated Requirement. A TN3161 explica o que essa checagem garante: todos os arquivos esperados estão lá, nenhum foi adicionado, nenhum foi alterado. Num bundle de teste que eu assinei e depois mexi, o comando responde a sealed resource is missing or invalid, depois file modified: seguido do arquivo alterado. A opção --deep serve aqui para verificar, nunca para assinar: no fórum da Apple, um engenheiro do time de suporte desaconselha usá-la para assinar.
3. Qual perfil está embutido?
security cms -D -i ipa/Payload/*.app/embedded.mobileprovision -o profil.plist
plutil -extract ProvisionedDevices xml1 -o - profil.plist
plutil -extract ExpirationDate raw profil.plist
Esses são os comandos da nota TN3125 sobre perfis. Um perfil App Store não contém nenhuma lista de aparelhos: a segunda linha deve responder Could not extract value. Se ela mostrar identificadores de aparelhos, é um perfil ad hoc, o de um build interno. A terceira mostra a data de expiração do perfil.
4. As extensões e os frameworks estão assinados do mesmo jeito?
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
-exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
Cada componente deve mostrar a mesma linha Authority do app. Se algum for diferente, é ele que a mensagem cita.
Se você quiser verificar antes do envio, a TN3161 recomenda o altool, a mesma checagem do botão Validate App do Xcode. Ele pede uma chave de API do App Store Connect, cujo arquivo AuthKey_<KEY_ID>.p8 fica em ~/.appstoreconnect/private_keys:
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
Corrigir com o EAS, causa por causa
Um build interno ou de desenvolvimento enviado à Apple
Segundo a documentação do Expo sobre o eas.json, os builds com "distribution": "internal" não são assinados para as lojas: eles usam um perfil ad hoc. Só um perfil com distribuição store, o valor padrão, gera um build que pode ser enviado. O mais seguro é enviar o build que você acabou de gerar, sem escolher na mão:
eas build --platform ios --profile production --auto-submit
Se você usa eas submit --path, confira se o arquivo é mesmo o seu último build store. No fórum da Apple, um time descobriu que a ferramenta de envio deles mandava sempre um IPA antigo, versionado no git.
Uma extensão esquecida
Cada extensão é um bundle separado, com seu identificador e seu próprio perfil. Num projeto Expo com geração nativa, a página do Expo sobre extensões iOS pede para declará-las em extra.eas.build.experimental.ios.appExtensions. Assim o EAS CLI as conhece antes do build e cria ou valida as credenciais delas. A maioria das bibliotecas que adicionam uma extensão escreve essa declaração para você, pelo plugin delas.
O Solys, meu despertador com minijogos, tem quatro extensões: um widget e três extensões de Screen Time. As quatro estão declaradas na configuração, e o EAS tem um perfil para cada uma. Uma extensão adicionada na mão no Xcode, sem essa declaração, é a candidata perfeita para um caminho em .appex na mensagem.
Um certificado revogado ou expirado
A página da Apple sobre certificados é clara: você não pode mais enviar um build assinado com um certificado expirado ou revogado. Um build já enviado mas ainda não submetido pode até passar para Invalid Binary se o certificado dele foi revogado.
O código do EAS CLI 24.10.0 mostra quando esse caso passa despercebido:
- Build interativo, conectado à Apple: o EAS compara o certificado dele com os que ainda são válidos na Apple. Se ele não estiver mais lá, mostra "Current distribution certificate is no longer valid in Apple Dev Portal" e propõe escolher ou criar outro.
- Build interativo, sem conexão: o EAS só verifica as datas e avisa que está pulando a validação na Apple.
- Build não interativo, em integração contínua: o EAS mostra "Distribution Certificate is not validated for non-interactive builds" e assina mesmo assim.
Em integração contínua, o EAS não verifica de novo o certificado em si: uma revogação pode só aparecer no envio. A correção: rode um build interativo conectado à sua conta Apple, ou use eas credentials --platform ios, menu Build Credentials, depois "Distribution Certificate: Add a new one to your account". Os perfis que continham o certificado antigo ficam inválidos: o EAS os verifica no próximo build e os refaz. Os limites da Apple sobre o número de certificados estão detalhados no guia sobre o certificado de desenvolvedor iOS.
Um binário alterado depois da assinatura
A assinatura sela o código, os recursos e os metadados com hashes, como explica a nota TN3126 da Apple. Descompactar o IPA para mudar um arquivo e compactar de novo quebra esse selo. Faça a alteração na sua configuração e depois refaça o build. Nunca mexa no IPA gerado pelo EAS.
A mesma lógica vale para código guardado no lugar errado, por exemplo dentro de um arquivo .zip: a App Store não consegue assiná-lo de novo. A Apple descreve os locais permitidos na página sobre o conteúdo de um bundle.
Credenciais locais
Se o seu perfil do EAS usa "credentialsSource": "local", seu arquivo credentials.json aponta para um certificado .p12 e um perfil .mobileprovision. Verifique o perfil com os comandos da etapa 3: ele deve ser do tipo App Store e conter seu certificado de distribuição atual. E mantenha esses arquivos fora do repositório, como as chaves de API de um app Expo.
Quando tudo está válido
Sobra um caso frustrante. No fórum da Apple, desenvolvedores veem o erro sumir reenviando o mesmo build, sem mudar nada. Em agosto e setembro de 2026, duas threads descrevem o contrário: certificado e perfil novos, assinatura verificada, falha persistente. Em uma delas, um engenheiro da Apple recomenda um relatório de bug com o IPA, a análise da assinatura e os logs do Transporter, e depois um contato com o App Store Connect.
Então reenvie uma vez com um novo número de build. Se o erro voltar com os seus quatro comandos limpos, reporte à Apple com esses elementos. Não revogue seu certificado por reflexo: isso não resolve nada a mais e invalida seus perfis.
Enviar seu build sem surpresa ruim
Uma assinatura se verifica em dois minutos antes do envio. As outras checagens automáticas pedem o mesmo cuidado, como o ITMS-90725 para a versão do Xcode ou o ITMS-90683 para as frases de permissão. O caminho completo do build ao envio, sem Mac, está em publicar um app iOS sem Mac.
As recusas de um reviewer pedem mais calma: o passo a passo está na página app recusado pela Apple, e os motivos mais comuns estão em por que a Apple recusa um app.
Para revisar seu app antes do envio, o Review Kit reúne meu checklist e skills do Claude Code que revisam seu projeto. Se o seu envio travou e você quer um olhar humano, agende uma hora comigo: a gente revisa seu projeto por vídeo, na sua tela. E se você está preparando seu primeiro lançamento, faça seu diagnóstico gratuito: ele coloca as etapas em ordem e te envia meu checklist anti-recusa da Apple.
Perguntas frequentes
O ITMS-90034 é uma recusa do App Review?
Não. É uma validação automática feita no envio do build, antes do TestFlight e antes de qualquer revisão. Ninguém abriu seu app: a Apple só constatou que a assinatura dele não vem de um certificado de distribuição válido.
Preciso revogar meu certificado de distribuição para corrigir o ITMS-90034?
Só se ele estiver comprometido ou já for inválido. Revogar um certificado que funciona invalida seus perfis sem corrigir a causa. Comece lendo a assinatura do seu IPA com codesign e depois corrija o que a árvore de decisão apontar.
Dá para corrigir o ITMS-90034 com uma atualização remota?
Não. A assinatura faz parte do binário, e o build recusado nunca vai poder ser usado. É preciso gerar um novo binário assinado corretamente e enviá-lo de novo.
Por que o erro cita meu widget e não meu app?
Porque o widget é um bundle separado, assinado com o próprio perfil. Se ele não foi declarado ao EAS ou foi assinado de outro jeito, ele derruba o envio inteiro. Declare a extensão na sua configuração e refaça o build.
O que fazer se o codesign diz que está tudo válido?
Verifique também o perfil embutido e cada extensão. Se tudo estiver limpo, reenvie uma vez com um novo número de build. Se o erro continuar, mande um relatório para a Apple com o IPA, a saída do codesign e os logs de envio.

