# eas submit iOS -virheet ja niiden korjaus

> Kaatuuko eas submit? EAS:n ja App Store Connectin oikeat virheviestit, syyt ja korjaukset: ascAppId, API-avain, Applen sopimus, ITMS-koodit.

Alkuperäinen sivu: [eas submit iOS -virheet ja niiden korjaus](https://devoria.fr/fi/blog/eas-submit-ios-virheet-korjaus)
Kirjoittaja: [Mehdi Azizi](https://devoria.fr/fi/mehdi-azizi)
Julkaistu: 2026-11-04
Sisältö tarkistettu viimeksi: 2026-11-04


Kun `eas submit --platform ios` epäonnistuu, viesti kertoo melkein aina, mistä kannattaa katsoa. **Joko EAS-asetuksesi ovat puutteelliset, Apple-tilisi estää lähetyksen tai Apple hylkää binäärin.** Kaksi ensimmäistä tapausta korjaantuvat muutamassa minuutissa ilman uutta buildia. Kolmannen tunnistaa ITMS-koodista, ja se vaatii melkein aina uuden buildin.

Julkaisen iOS-sovellukseni, muun muassa Solysin, TradaZenin ja Noleran, Expolla ja EAS:llä. Tässä lainatut viestit on kopioitu EAS CLI:n lähdekoodista [Expon virallisesta GitHub-repositoriosta](https://github.com/expo/eas-cli), jonka luin läpi 3. marraskuuta 2026. Expon vanha foorumi ohjaa nykyään Discordiin, joten koodi on edelleen varmin lähde. Jos haluat koko polun `eas.json`-tiedostosta tarkastukseen lähettämiseen asti, lue ensin [EAS Submit iOS: Expo-sovelluksen julkaisu App Storeen](https://devoria.fr/fi/blog/eas-submit-ios-expo-sovellus-app-store). Tässä keskitytään korjaamiseen.

## Mitä eas submit tekee ja mitä se tarvitsee

[Expon dokumentaation](https://docs.expo.dev/deploy/submit-to-app-stores/) mukaan komento lähettää `.ipa`-tiedostosi App Store Connectiin. Build ilmestyy TestFlightiin, kun Apple on käsitellyt sen, yleensä 10-15 minuutissa. **Komento ei lähetä sovellustasi tarkastukseen**: se pitää tehdä edelleen App Store Connectissa.

[Expon iOS-lähetyssivu](https://docs.expo.dev/submit/ios/) listaa kolme edellytystä:

- **maksullinen Apple Developer -tili**, jota vaaditaan kaikkiin App Store -lähetyksiin;
- **bundle-tunniste** kentässä `ios.bundleIdentifier`;
- **EAS CLI asennettuna** ja kirjautuneena Expo-tiliisi.

Jos haluat lähettää ilman vuorovaikutusta, sama sivu lisää kaksi asetusta:

- **`ascAppId`** `eas.json`-tiedoston `submit`-profiilissa, eli App Store Connect -sovelluksesi numero;
- **App Store Connect API-avain**, jota EAS hallinnoi tai jonka annat itse. Sen luonti, rooli ja peruminen on käyty läpi artikkelissa [App Store Connect API-avain (.p8)](https://devoria.fr/fi/blog/app-store-connect-api-avain-p8-luonti-kaytto).

Minimiprofiili mahtuu muutamalle riville. Arvo on keksitty:

```json
{
  "submit": {
    "production": {
      "ios": {
        "ascAppId": "1234567890"
      }
    }
  }
}
```

Jos EAS säilyttää jo API-avaintasi, tämä profiili riittää. Näin on useimmissa sovelluksissani.

## Viestin lukeminen: kolme virheperhettä

Ennen kuin etsit korjausta, katso, missä vaiheessa komento pysähtyy. Tämä taulukko on se ruudukko, jota käytän jokaisen epäonnistumisen kohdalla.

| Epäonnistumisen hetki                   | Perhe           | Uusi build?  |
| --------------------------------------- | --------------- | ------------ |
| Ennen mitään lähetystä                  | EAS-asetukset   | Ei           |
| Yhteys Appleen, sovellustietueen luonti | Apple-tili      | Ei           |
| Lähetyksen jälkeen, koodi ITMS-90xxx    | Hylätty binääri | Melkein aina |

Yksityiskohdat näkyvät lähetyksen sivulla Expon hallintapaneelissa. [Expo neuvoo](https://docs.expo.dev/deploy/submit-to-app-stores/) lukemaan sieltä lokit ja etsimään "Build Annotations" -kuplan, joka kertoo yleisimmistä epäonnistumisen syistä. Terminaalissa `--verbose`-valitsin näyttää EAS Submitin lokit aina, [EAS CLI:n referenssin](https://docs.expo.dev/eas/cli/) mukaan.

## EAS-asetusten virheet

### "Set ascAppId in the submit profile (eas.json) or re-run this command in interactive mode."

Ajoit komennon valitsimella `--non-interactive`, esimerkiksi jatkuvassa integraatiossa, eikä profiilissasi ole `ascAppId`:tä. [EAS CLI:n koodi](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/submit/ios/IosSubmitCommand.ts) pysähtyy silloin: se ei voi kysyä sinulta mitään eikä luoda sovellustietuetta puolestasi.

**Korjaus: kopioi sovelluksesi numero kenttään `ascAppId`.** [Expo kertoo, mistä sen löytää](https://github.com/expo/fyi/blob/main/asc-app-id.md): avaa sovelluksesi App Store Connectissa ja sitten App Information. Se on Apple ID -kenttä kohdassa General Information, noin kymmennumeroinen luku. Se ei ole Apple-sähköpostiosoitteesi eikä bundle-tunnisteesi.

Nolerassa komento vaati ilman `ascAppId`:tä Apple Developer -istunnon, joka vanhenee. Siitä asti kun numero on ollut `eas.json`-tiedostossa, lähetys ei ole kysynyt mitään.

> Lisää `ascAppId` ennen buildia, ei sen jälkeen. SDK 57:ään asti [Expon laskema sormenjälki](https://github.com/expo/expo/blob/main/packages/@expo/fingerprint/src/sourcer/Expo.ts) sisältää aina `eas.json`-tiedoston. Vigiessä, jonka ajonaikainen versio noudattaa `fingerprint`-käytäntöä, numeron lisääminen buildin jälkeen muutti sormenjäljen: sen jälkeen julkaistu päivitys ei olisi koskaan päätynyt asennettuun buildiin. SDK 58:sta lähtien sormenjäljen oletusasetus `balanced` ohittaa `eas.json`-tiedoston, [Expon muutoslokin](https://github.com/expo/expo/blob/main/packages/@expo/fingerprint/CHANGELOG.md) mukaan.

### "App Store Connect API Keys cannot be set up in --non-interactive mode."

Profiilissasi ei ole avainta, eikä EAS:llä ole yhtään sovellukseesi liitettyä avainta. [Expo tarkentaa](https://docs.expo.dev/submit/ios/): ei-interaktiivisessa tilassa komento ei voi pyytää sinulta avainta, ja se kaatuu tähän viestiin.

Kaksi mahdollista korjausta:

- **Anna EAS:n luoda ja säilyttää avain.** Aja kerran `eas credentials --platform ios` interaktiivisessa tilassa omalla koneellasi ja anna sen määrittää App Store Connect API-avain sovelluksellesi.
- **Tuo oma avaimesi** kenttiin `ascApiKeyPath`, `ascApiKeyIssuerId` ja `ascApiKeyId`. [eas.json-referenssin](https://docs.expo.dev/eas/json/) mukaan nämä kolme kenttää hyväksyvät ympäristömuuttujia, kuten `$ASC_API_KEY_PATH`.

Viimeisimmässä sovelluksessani `--auto-submit`-valitsin halusi Apple-tunnuksen luodakseen lähetysavaimensa. Laitoin oman avaimeni kolme kenttää työkopioni profiiliin, jota en koskaan commitoinut. Sitten lähetin valmiin buildin valitsimilla `--id` ja `--non-interactive`.

### "EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format xxxx-xxxx-xxxx-xxxx, where x is a lowercase letter."

Muuttuja sisältää jotain muuta kuin sovelluskohtaisen salasanan, usein itse Apple-salasanasi. [EAS CLI](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/submit/ios/IosSubmitCommand.ts) tarkistaa tämän muodon ennen mitään lähetystä.

[Applen ohjeen](https://support.apple.com/en-us/102654) mukaan sovelluskohtainen salasana luodaan osoitteessa account.apple.com kohdassa App-Specific Passwords, kun kaksivaiheinen todennus on päällä. Se perutaan heti, kun vaihdat Apple-tilisi salasanan. **Expo pitää tätä tapaa [vähemmän turvallisena kuin API-avainta](https://github.com/expo/fyi/blob/main/apple-app-specific-password.md), joka on sen oletus ja suositus.**

## Apple-tilin virheet

### "… agree to the latest Program License Agreement in your developer account."

Koko viesti alkaa sanoilla "You currently don't have access to this membership resource". Applen raaka vastaus voi sisältää "Unable to process request - PLA Update available". EAS:n uudemmat lähetysvaiheet näyttävät mieluummin "A required Apple agreement is missing or has expired".

Syy on sama: Apple on päivittänyt sopimuksen, eikä kukaan ole hyväksynyt sitä. **Vain tilin omistaja, Account Holder, voi hyväksyä sopimukset**, [Applen roolitaulukon](https://developer.apple.com/help/account/access/roles/) mukaan. [EAS:n koodi](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiClient.ts) pyytää häntä käymään App Store Connectin Business-sivulla ja sitten, jos Apple sitä tarjoaa, omalla tilillään osoitteessa developer.apple.com. Aja komento sen jälkeen uudelleen. Maksullisten sovellusten sopimukselle on oma oppaansa: [Paid Apps Agreement App Store Connectissa](https://devoria.fr/fi/blog/paid-apps-agreement-tilat-w-8ben-ensimmainen-maksu).

### "App Store Connect rejected the API authentication credentials."

Apple vastasi virheellä 401, `NOT_AUTHORIZED`. [EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiClient.ts) mainitsee kolme syytä: avain ei ole enää aktiivinen, avain kuuluu toiseen App Store Connect -tiliin, tai Key ID, avaimen sisältö tai Issuer ID on väärin.

Tarkista molemmat tunnisteet App Store Connectissa: valikko Users and Access, välilehti Integrations. [Applen](https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests) mukaan Issuer ID näkyy sivun yläreunassa ja Key ID aktiivisten avainten listassa. **Perutettua avainta ei voi koskaan aktivoida uudelleen.** [Apple näyttää sen](https://developer.apple.com/documentation/appstoreconnectapi/revoking-api-keys) 30 päivää kohdassa Revoked: sinun pitää luoda uusi.

### "App Store Connect app for application identifier … was not found."

`ascAppId`:n osoittamaa sovellustietuetta ei löydy avaimellasi. [EAS](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/utils/ios/AscApiUtils.ts) pyytää tarkistamaan numeron ja sen, että avaimella on pääsy sovellukseen oikealla tilillä. Se jopa listaa muutaman avaimella näkyvän sovelluksen. Applen omilla lähetystyökaluilla sama ongelma näkyy muodossa "No suitable application records were found".

Kolme syytä toistuu, joista kaksi on mainittu [tässä Applen foorumiketjussa](https://developer.apple.com/forums/thread/106806):

- **Sovellustietuetta ei ole olemassa.** Luo se App Store Connectissa tai poista `ascAppId`, jotta komento luo sen.
- **Numero on toiselta tililtä.** Kopioit `ascAppId`:n toiselta tiimiltä tai toisesta projektista.
- **Käyttäjällä ei ole pääsyä sovellukseen.** App Manager tai Developer voi olla rajattu tiettyihin sovelluksiin. Tiimiavaimella taas on [pääsy kaikkiin tilin sovelluksiin](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api).

### "… is not available to team" tai "… is not available to provider"

Tämä viesti tulee, kun EAS luo sovellustietueen puolestasi, koska `ascAppId` puuttuu. Bundle-tunniste on jo toisen tiimin käytössä. [EAS pyytää](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/credentials/ios/appstore/ensureAppExists.ts) vaihtamaan sen sovelluksesi asetuksissa ja ajamaan komennon uudelleen.

### "App name "…" is already taken. Using generated name "…""

Tämä ei ole epäonnistuminen. Kun nimi on jo varattu App Storessa, EAS lisää kuusi satunnaista merkkiä ja yrittää uudelleen, enintään viisi kertaa. Voit nimetä sovellustietueen myöhemmin uudelleen App Store Connectissa. Välttääksesi tämän täytä profiiliin `appName` ja `language` ennen ensimmäistä lähetystä: ilman `language`-kenttää [ensisijainen kieli on `en-US`](https://docs.expo.dev/eas/json/).

## Binäärin virheet: ITMS-koodit

Lähetyksen jälkeen Apple käsittelee buildin. Jos se hylkää sen, lokissa mainitaan yksi tai useampi ITMS-koodi. Tässä ne, jotka [EAS:n lähetysvaihe](https://github.com/expo/eas-cli/blob/main/packages/build-tools/src/steps/functions/uploadToAsc.ts) tunnistaa ja selittää:

| ITMS-koodi                 | Mitä Apple hylkää                      | Korjaus                |
| -------------------------- | -------------------------------------- | ---------------------- |
| 90189                      | Build-numero on jo käytössä            | `autoIncrement`        |
| 90062, 90186, 90478        | Versio suljettu tai jo ohitettu        | Nosta `version`        |
| 90683                      | Käyttöoikeuden perustelu puuttuu       | `ios.infoPlist`        |
| 90725                      | Liian vanha iOS SDK                    | iOS-image tai Expo SDK |
| 90054, 90055               | Bundle eri kuin kohdesovelluksen       | Korjaa `ascAppId`      |
| 90022, 90023, 90391, 90713 | Ikonit puuttuvat tai väärin määritelty | Tarkista ikonit        |
| 90771                      | Taustatehtävien tunnisteet puuttuvat   | `ios.infoPlist`        |

Kolme tarkennusta näistä viesteistä:

- **Build-numero on yksilöllinen versiota kohden.** Koodille 90189 EAS suosittelee `"autoIncrement": true` `eas.json`-tiedostossa. Kaikki on kerrottu artikkelissa [build-numero ja versio](https://devoria.fr/fi/blog/app-store-connect-build-number-versio-buildinumero).
- **Koodille 90725** EAS neuvoo valitsemaan uudemman iOS-imagen `eas.json`-tiedostossa ja tarvittaessa siirtymään tuettuun Expo SDK:hon.
- **Koodissa 90771** Info.plist ilmoittaa taustatilan `processing` mutta ei avainta `BGTaskSchedulerPermittedIdentifiers`.

Koodeja 90054 ja 90055 lukuun ottamatta, joissa riittää osoittaa oikeaan sovellukseen tai toiseen buildiin, **korjaus koskee binääriä: tee uusi build ja lähetä se uudelleen.** Kahdelle koodille on oma oppaansa: [ITMS-90683 Expolla](https://devoria.fr/fi/blog/itms-90683-missing-purpose-string-expo) ja [ITMS-90725](https://devoria.fr/fi/blog/itms-90725-sdk-version-issue-expo).

Syyskuun lopussa 2026 Solysin build hylättiin toimituksessa koodilla ITMS-90683. Olin poistanut kuvia koskevan käyttöoikeuden perustelun siivotessani asetustiedostoa. Solys ei käytä kuvia, mutta yksi projektin kirjastoista kutsuu iOS:n Photos-rajapintaa. **Apple analysoi binäärin, ei todellista käyttöä:** siitä lähtien en ole enää koskaan poistanut näitä perusteluja.

Missing Compliance -tila taas ei ole lähetysvirhe. Siitä puuttuu salausta koskeva ilmoituksesi, jota käsitellään [EAS-julkaisuoppaassa](https://devoria.fr/fi/blog/eas-submit-ios-expo-sovellus-app-store).

## Tarkistuslistani ennen jokaista lähetystä

- `ascAppId` on `submit`-profiilissa, lisättynä ennen buildia.
- API-avainta hallinnoi EAS, tai sen kolme kenttää osoittavat repositorion ulkopuolella säilytettyyn `.p8`-tiedostoon.
- Account Holder on hyväksynyt uusimmat sopimukset App Store Connectissa.
- `autoIncrement` on päällä yhdessä asetuksen `"appVersionSource": "remote"` kanssa, jota [Expo suosittelee](https://docs.expo.dev/build-reference/app-versions/) EAS CLI 12:sta lähtien.
- `version` on suurempi kuin viimeisin hyväksytty versio.
- Jokaisella binäärissä olevalla arkaluonteisella rajapinnalla on käyttöoikeuden perustelunsa.
- Uudelle sovellukselle `appName` ja `language` on täytetty ennen ensimmäistä lähetystä.

## Lähetä ensimmäinen sovelluksesi jumittumatta

Komento on vain yksi vaihe. [iOS & Android Kit](https://devoria.fr/fi/kits/ios) lähtee liikkeelle sovellusteni aloituskoodista tilauksineen ja etenee neljässä vaiheessa App Storeen asti, omaan tahtiisi.

Jos valmistelet ensimmäistä julkaisuasi, [tee ilmainen diagnoosi](https://devoria.fr/fi/diagnostic): se kertoo, mikä sinua oikeasti jarruttaa, ja lähettää sinulle tarkistuslistani Applen hylkäysten välttämiseen. Sovellussivun, kuvakaappausten ja hyväksynnän osalta sivu [sovelluksen julkaisu App Storessa](https://devoria.fr/fi/expertise/julkaise-sovellus-app-storeen) käy läpi jokaisen vaiheen.

## Usein kysytyt kysymykset

### Miksi eas submit epäonnistuu vain jatkuvassa integraatiossa?

`--non-interactive`-tilassa komento ei voi kysyä sinulta mitään. Se tarvitsee profiiliin `ascAppId`:n ja sovellukseen jo liitetyn API-avaimen, tai avaimen kolme kenttää `eas.json`-tiedostoon. Omalla koneellasi se olisi kysynyt nämä sinulta.

### Pitääkö eas submit -virheen jälkeen tehdä uusi build?

Vain jos Apple hylkää binäärin ITMS-koodilla. Poikkeus: koodeissa ITMS-90054 ja 90055 build osoitti väärään sovellukseen, ja riittää lähettää se oikeaan. Asetus- ja tilivirheet korjataan `eas.json`-tiedostossa, App Store Connectissa tai Apple-tililläsi. Sen jälkeen lähetät saman buildin uudelleen, esimerkiksi valitsimella `--latest` tai `--id`.

### Mistä näen EAS Submit -lähetyksen lokit?

Lähetyksen sivulta Expon hallintapaneelista. Expo neuvoo lukemaan sieltä lokit ja "Build Annotations" -kuplan. Terminaalissa lisää `--verbose`, niin lokit näkyvät aina.

### Voiko eas submitia käyttää ilmaisella Apple-tilillä?

Ei. Expo vaatii maksullisen Apple Developer -tilin sovelluksen lähettämiseen App Storeen. Ilmaisella tilillä voit testata omalla iPhonellasi, mutta et käyttää App Store Connectia.

### Mikä rooli API-avaimelle kannattaa antaa eas submitia varten?

Expon opas antaa avaimelle Admin-roolin. Applen roolitaulukon mukaan buildien lähettäminen on sallittu myös rooleille App Manager ja Developer. Expo-buildini pyörivät tiimiavaimella, jonka rooli on App Manager. Vain Account Holder ja Adminit voivat luoda tiimiavaimen.

### Mitä "Increment Build Number" tarkoittaa EAS:ssä?

Apple hylkäsi buildin koodilla ITMS-90189: tämä build-numero on jo olemassa tälle versiolle. Ota käyttöön `"autoIncrement": true` `eas.json`-tiedostossa tai nosta `ios.buildNumber`, ja tee sitten uusi build.


## Projektisi

[Review Kit](https://devoria.fr/fi/kits/app-review): App Store -tarkastuksen tarkistuslistani, korjatut Applen hylkäykseni, Google Playn lista ja kolme Claude Code -skilliä. 49 €.

[iOS & Android Kit](https://devoria.fr/fi/kits/ios): Tee iPhone- ja Android-sovelluksesi Claude Codella: sovellusteni pohjakoodi, polku kauppoihin asti ja kaikki kitit. 99 €.

[Diagnoosi: mikä erottaa sinut omasta iPhone-sovelluksestasi](https://devoria.fr/fi/diagnostic): 7 kysymystä, 60 sekuntia: tiedät, mikä oikeasti estää sinua julkaisemasta iPhone-sovellustasi, saat 4 vaiheen polkusi ja sinulle sopivan kitin.
