# ITMS-90034: cómo corregir “Missing or invalid signature”

> ITMS-90034: tu build no está firmado con un certificado de distribución válido. Revisa su firma con codesign y vuelve a hacer un build store con EAS.

Página original: [ITMS-90034: cómo corregir “Missing or invalid signature”](https://devoria.fr/es/blog/itms-90034-missing-or-invalid-signature)
Autor: [Mehdi Azizi](https://devoria.fr/es/mehdi-azizi)
Publicación: 2026-11-04
Última revisión del contenido: 2026-11-04


ITMS-90034 aparece cuando envías tu build a App Store Connect. Te dice que tu app, o uno de sus componentes, no está firmada con un certificado de envío de Apple, es decir, con un certificado de distribución válido. **La solución: encontrar qué bundle está mal firmado y por qué, y luego hacer un nuevo build firmado para el App Store.**

Esta guía se centra en el error. Si las palabras certificado y perfil no te quedan claras, lee primero [certificado de desarrollador iOS y provisioning profile](https://devoria.fr/es/blog/certificado-ios-provisioning-profile-expo). Aquí encontrarás el mensaje que hay que leer, un árbol de decisión, los comandos para inspeccionar tu IPA y la corrección con las credenciales gestionadas por EAS. Para la parte de EAS, leí el código de EAS CLI 24.10.0 que elige el certificado.

## ¿Qué significa el error ITMS-90034?

Esta es su forma clásica, con nombres de ejemplo:

> 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.

En 2026, en el foro de Apple, también aparece como "Validation failed (409) Missing or invalid signature", seguido del mismo texto y de "(ID: 90034)".

El "certificado de envío" es el certificado de distribución. [La ayuda de Apple sobre certificados](https://developer.apple.com/help/account/certificates/certificates-overview) lo dice: los certificados de desarrollo sirven para ejecutar tu app en tus dispositivos, y los de distribución para distribuirla o enviarla a App Store Connect.

**Lee la ruta citada: señala el bundle culpable.** `Payload/MyApp.app` apunta a la app en sí. Una ruta que termina en `.appex` apunta a una extensión, como un widget. Una ruta en `.framework` apunta a una biblioteca integrada.

No es el rechazo de un revisor. La validación falla al enviar o durante el procesamiento del build, antes de TestFlight: este build nunca llegará a tus testers.

## El árbol de decisión: del mensaje a la solución

Cada fila corresponde a una pista que lees en el mensaje, en los comandos de la siguiente sección o en los logs de EAS. Revísalas en orden: la primera que coincida te da el camino.

| Lo que observas              | Causa probable              | Solución                  |
| ---------------------------- | --------------------------- | ------------------------- |
| Ruta en `.appex`             | Extensión mal firmada       | Declarar la extensión     |
| `Signature=adhoc`            | Build sin firmar            | Build con perfil store    |
| `Apple Development`          | Build de desarrollo         | Build con perfil store    |
| Aparece `ProvisionedDevices` | Build interno (ad hoc)      | Build con perfil store    |
| `sealed resource`            | IPA modificada después      | Rehacer el build          |
| EAS: "no longer valid"       | Certificado revocado        | Nuevo certificado         |
| Todo es válido               | Incidente del lado de Apple | Reenviar y luego reportar |

## Inspeccionar tu IPA en cuatro comandos

Descarga la IPA desde la página del build en expo.dev y abre una terminal en tu Mac.

**1. ¿Quién firmó la app?**

```bash
unzip -q MyApp.ipa -d ipa
codesign -dv --verbose=4 ipa/Payload/*.app 2>&1 | grep -E "^(Identifier|Authority|Signature|TeamIdentifier)="
```

`codesign` escribe en la salida de error, de ahí el `2>&1`. Según [la nota técnica TN3161 de Apple](https://developer.apple.com/documentation/technotes/tn3161-inside-code-signing-certificates), cada línea `Authority` es un eslabón de la cadena de confianza. La primera debe empezar por `Apple Distribution:` o `iPhone Distribution:`, seguida del nombre de tu equipo. La segunda etiqueta corresponde al antiguo tipo iOS Distribution: según su código, EAS CLI 24.10.0 todavía crea certificados de ese tipo. Si lees `Apple Development:`, es un build de desarrollo. Si lees `Signature=adhoc` sin ninguna línea `Authority`, el binario no está firmado por ningún certificado.

**2. ¿Se modificó la app después de firmarla?**

```bash
codesign --verify --deep --strict -vv ipa/Payload/*.app
```

Quieres leer `valid on disk` y luego `satisfies its Designated Requirement`. TN3161 precisa lo que garantiza esta verificación: están todos los archivos esperados, no se agregó ninguno y no se modificó ninguno. En un bundle de prueba que firmé y luego retoqué, el comando responde `a sealed resource is missing or invalid` y después `file modified:` seguido del archivo cambiado. La opción `--deep` sirve aquí para verificar, nunca para firmar: en el foro de Apple, un ingeniero del equipo de soporte desaconseja usarla para firmar.

**3. ¿Qué perfil está integrado?**

```bash
security cms -D -i ipa/Payload/*.app/embedded.mobileprovision -o profile.plist
plutil -extract ProvisionedDevices xml1 -o - profile.plist
plutil -extract ExpirationDate raw profile.plist
```

Son los comandos de [la nota TN3125 sobre perfiles](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles). Un perfil App Store no contiene ninguna lista de dispositivos: la segunda línea debe responder `Could not extract value`. Si muestra identificadores de dispositivos, es un perfil ad hoc, el de un build interno. La tercera da la fecha de vencimiento del perfil.

**4. ¿Las extensiones y los frameworks están firmados igual?**

```bash
find ipa/Payload/*.app \( -name "*.appex" -o -name "*.framework" \) \
  -exec sh -c 'echo "$1"; codesign -dvv "$1" 2>&1 | grep -m1 "^Authority="' _ {} \;
```

Cada componente debe mostrar la misma línea `Authority` que la app. Si alguno se aparta, es el que cita el mensaje.

Si quieres verificar antes de enviar, TN3161 recomienda `altool`, la misma verificación que el botón Validate App de Xcode. Requiere una clave API de App Store Connect, cuyo archivo `AuthKey_<KEY_ID>.p8` se guarda en `~/.appstoreconnect/private_keys`:

```bash
xcrun altool --validate-app -f MyApp.ipa -t ios --api-key <KEY_ID> --api-issuer <ISSUER_ID>
```

## Corregir con EAS, causa por causa

### Un build interno o de desarrollo enviado a Apple

Según la [documentación de Expo sobre eas.json](https://docs.expo.dev/build/eas-json/), los builds con `"distribution": "internal"` no están firmados para las tiendas: usan un perfil ad hoc. Solo un perfil con distribución `store`, el valor por defecto, produce un build que se puede enviar. **Lo más seguro es enviar el build que acabas de generar, sin elegirlo a mano**:

```bash
eas build --platform ios --profile production --auto-submit
```

Si usas `eas submit --path`, verifica que el archivo sea realmente tu último build store. En el foro de Apple, un equipo descubrió que su herramienta de envío mandaba cada vez una IPA antigua, versionada en git.

### Una extensión olvidada

Cada extensión es un bundle aparte, con su identificador y su propio perfil. En un proyecto Expo con generación nativa, la [página de Expo sobre extensiones iOS](https://docs.expo.dev/build-reference/app-extensions/) pide declararlas en `extra.eas.build.experimental.ios.appExtensions`. Así EAS CLI las conoce antes del build y crea o valida sus credenciales. La mayoría de las bibliotecas que agregan una extensión escriben esa declaración por ti, mediante su plugin.

Solys, mi despertador con minijuegos, incluye cuatro extensiones: un widget y tres extensiones de Screen Time. Las cuatro están declaradas en su configuración y EAS tiene un perfil para cada una. **Una extensión agregada a mano en Xcode, sin esa declaración, es el candidato ideal** para una ruta en `.appex` en el mensaje.

### Un certificado revocado o vencido

La [página de Apple sobre certificados](https://developer.apple.com/support/certificates/) es clara: ya no puedes enviar un build firmado con un certificado vencido o revocado. Un build ya enviado pero todavía no sometido a revisión puede incluso pasar a Invalid Binary si su certificado fue revocado.

El código de EAS CLI 24.10.0 muestra cuándo este caso pasa desapercibido:

- **Build interactivo, conectado a Apple**: EAS compara su certificado con los que siguen válidos en Apple. Si ya no está, muestra "Current distribution certificate is no longer valid in Apple Dev Portal" y te propone elegir o crear uno.
- **Build interactivo, sin conexión**: EAS solo verifica las fechas y avisa que omite la validación con Apple.
- **Build no interactivo, en integración continua**: EAS muestra "Distribution Certificate is not validated for non-interactive builds" y firma de todos modos.

**En integración continua, EAS no vuelve a verificar el certificado en sí: una revocación puede notarse solo al enviar.** La solución: lanza un build interactivo conectado a tu cuenta de Apple, o usa `eas credentials --platform ios`, menú Build Credentials, y luego "Distribution Certificate: Add a new one to your account". Los perfiles que contenían el certificado anterior quedan inválidos: EAS los revisa en el siguiente build y los vuelve a generar. Los límites de Apple sobre la cantidad de certificados están detallados en la [guía sobre el certificado de desarrollador iOS](https://devoria.fr/es/blog/certificado-ios-provisioning-profile-expo).

### Un binario modificado después de la firma

La firma sella el código, los recursos y los metadatos mediante hashes, como explica [la nota TN3126 de Apple](https://developer.apple.com/documentation/technotes/tn3126-inside-code-signing-hashes). Descomprimir la IPA para cambiar un archivo y volver a comprimirla rompe ese sello. **Haz el cambio en tu configuración y vuelve a hacer un build.** Nunca retoques la IPA generada por EAS.

La misma lógica aplica al código guardado en el lugar equivocado, por ejemplo dentro de un archivo `.zip`: el App Store no puede volver a firmarlo. Apple describe las ubicaciones permitidas en su página sobre [el contenido de un bundle](https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle).

### Credenciales locales

Si tu perfil de EAS usa `"credentialsSource": "local"`, tu archivo `credentials.json` apunta a un certificado `.p12` y a un perfil `.mobileprovision`. Verifica el perfil con los comandos del paso 3: debe ser de tipo App Store y contener tu certificado de distribución actual. Y mantén esos archivos fuera del repositorio, igual que [las claves API de una app Expo](https://devoria.fr/es/blog/clave-api-secreta-expo-que-proteger).

### Cuando todo es válido

Queda un caso frustrante. En el foro de Apple, algunos desarrolladores ven desaparecer el error al reenviar el mismo build, sin cambiar nada. En agosto y septiembre de 2026, dos hilos describen lo contrario: certificado y perfil nuevos, firma verificada, y el error persiste. En uno de ellos, un ingeniero de Apple recomienda un reporte de bug con la IPA, el análisis de la firma y los logs de Transporter, y luego contactar a App Store Connect.

Así que reenvía una vez con un nuevo número de build. Si el error vuelve aunque tus cuatro comandos salgan limpios, repórtalo a Apple con esos elementos. **No revoques tu certificado por reflejo**: no resuelve nada más e invalida tus perfiles.

## Enviar tu build sin sorpresas

Una firma se verifica en dos minutos antes de enviar. Las demás verificaciones automáticas piden el mismo rigor, como [ITMS-90725](https://devoria.fr/es/blog/itms-90725-sdk-version-issue-expo) para la versión de Xcode o [ITMS-90683](https://devoria.fr/es/blog/itms-90683-missing-purpose-string-expo) para los textos de permisos. El recorrido completo del build al envío, sin Mac, está en [publicar una app iOS sin Mac](https://devoria.fr/es/blog/publicar-app-ios-sin-mac-expo-eas).

Los rechazos de un revisor requieren más perspectiva: el proceso está en la página [app rechazada por Apple](https://devoria.fr/es/expertise/app-rechazada-por-apple), y los motivos más frecuentes están en [por qué Apple rechaza una app](https://devoria.fr/es/blog/rechazo-apple-por-que-rechazan-tu-app).

Para revisar tu proyecto antes de enviarlo, el [Review Kit](https://devoria.fr/es/kits/app-review) reúne mi checklist y skills de Claude Code que revisan tu proyecto. Si tu envío se traba y quieres una mirada humana, [reserva una hora conmigo](https://devoria.fr/es/coaching): revisamos tu proyecto por videollamada, en tu pantalla. Y si estás preparando tu primer lanzamiento, [haz tu diagnóstico gratuito](https://devoria.fr/es/diagnostic): ordena los pasos y te envía mi checklist anti-rechazo de Apple.

## Preguntas frecuentes

### ¿ITMS-90034 es un rechazo de App Review?

No. Es una validación automática que se hace al enviar el build, antes de TestFlight y antes de cualquier revisión. Nadie abrió tu app: Apple solo detectó que su firma no proviene de un certificado de distribución válido.

### ¿Hay que revocar mi certificado de distribución para corregir ITMS-90034?

Solo si está comprometido o ya es inválido. Revocar un certificado que funciona invalida tus perfiles sin corregir la causa. Empieza por leer la firma de tu IPA con `codesign` y luego corrige lo que señale el árbol de decisión.

### ¿Se puede corregir ITMS-90034 con una actualización remota?

No. La firma forma parte del binario, y el build rechazado nunca se podrá usar. Hay que generar un nuevo binario bien firmado y volver a enviarlo.

### ¿Por qué el error cita mi widget y no mi app?

Porque el widget es un bundle aparte, firmado con su propio perfil. Si no está declarado en EAS o se firmó de otra forma, hace fallar todo el envío. Declara la extensión en tu configuración y vuelve a hacer un build.

### ¿Qué hago si codesign dice que todo es válido?

Verifica también el perfil integrado y cada extensión. Si todo está limpio, reenvía una vez con un nuevo número de build. Si el error persiste, envía un reporte a Apple con la IPA, la salida de `codesign` y los logs de envío.


## Tu proyecto

[Review Kit](https://devoria.fr/es/kits/app-review): Mi checklist de revisión de App Store, mis rechazos de Apple corregidos, la de Google Play y tres skills de Claude Code. 49 €.

[iOS & Android Kit](https://devoria.fr/es/kits/ios): Crea tu app para iPhone y Android con Claude Code: el código base de mis apps, el camino hasta las tiendas y todos los kits. 99 €.

[Diagnóstico: lo que te separa de tu app para iPhone](https://devoria.fr/es/diagnostic): 7 preguntas, 60 segundos: descubre qué te frena de verdad para publicar tu app para iPhone, tu ruta en 4 etapas y el kit ideal para ti.
