Late October 2026
Builds
Added
- Capacitor iOS builds can now be signed with more than one provisioning
profile, for projects that include an app extension such as a share
extension. List the extra profiles in
voltbuilder.jsonas project-relative paths:iosDevelopmentExtrafor a debug build,iosDistributionExtrafor a release build. Each target is signed with the profile whose bundle identifier matches it, an exact match first and otherwise the longest wildcard match, and the same set of profiles is used when the archive is exported. If a target has no matching profile the build stops with “No provisioning profile found for iOS target” and the target’s name and bundle identifier. An extra profile path that does not exist, points outside the project, or is not a file is rejected by the pre-build check, and a profile with a malformed UUID gives a “Malformed mobileprovision” error. See Signing app extensions in the Capacitor setup guide. - The documentation now has a Build environment
page listing the tools and versions on the Android and iOS build servers. For
Android it covers the operating system, Node.js, npm, the Cordova CLI, Gradle,
Kotlin, the JDKs, and the Android build-tools and platforms. It also gives the
JDK, build-tools and platform used for each
cordova-androidrelease, and which Java version Cordova and Capacitor builds use. For iOS it lists macOS, Xcode, Node.js, npm, the Cordova CLI, CocoaPods and the pre-cachedcordova-iosversions.
Changed
- In Capacitor iOS builds, the manual signing settings are now applied only to the app, app extension, watch and App Clip targets, and only to the configuration being built: Debug for a debug build, Release for a release build. Before, every Debug and Release configuration that set a signing style was switched to your profile, and frameworks and static libraries in the project were not exempt. A project with an extension target and no profile that matches it, which previously built with your single profile applied to everything, now stops with the “No provisioning profile found” error above.
- The comparison table on the About page now shows the current Xcode (26.2), Cordova (13.0.0) and Android API (36.1) versions. It previously showed Xcode 13.4.0, Cordova 10.1.1 and Android API 30.
Uploads
Fixed
- If your subscription had expired, the upload page told you “Your account is not authorized to use the build service. Please contact support.” It now says “Your subscription expired on” followed by the date, asks you to renew your plan before uploading, and links to the plans page. The upload buttons stay disabled.
- If the upload page could not load your build status when it opened, the upload buttons stayed disabled after a later Check status succeeded, until you reloaded the page. They are now enabled again as soon as the status check succeeds.
- When the sign-in service timed out while the upload page was refreshing your session, the page told you “Authentication error: Timeout when executing ‘fetch’. Please log in again.”, and if it was following a build it stopped and showed the Log in button. A timeout is now handled like any other connection problem: the message says the sign-in service could not be reached and to check your connection, and during a build the Check status button is shown instead of Log in.
Changed
- While the upload page is following a build, it now refreshes your sign-in token before each status check, so a page left open for a long time keeps checking. If you need to sign in again, the page stops checking and shows the Log in button. If the token cannot be refreshed because of a network problem, it stops and keeps the Check status button. Either way the message says that your upload was accepted, that the build may still be running, and that the interruption does not mean the build failed.
- If the script that reads your plan from your sign-in token fails to load, the upload page now says “Upload is temporarily unavailable. Please refresh and try again.”, hides the login buttons and leaves uploads disabled.
API
Added
POST /v1/appnow returns anX-Request-IDresponse header on 401 responses as well, so a rejected upload carries an ID you can send us. On this route the value is a short hash of theX-Request-IDorX-Correlation-IDyou sent, not the ID itself, and if you send neither it is generated. If you have a problem with the API, send us the request ID and we can find that request in our logs.