Skip to main content

Security — Error Codes

UpdateErrorCode is the canonical enum the plugin throws for every typed failure across all four feature areas. Errors come back as UpdateError objects:

interface UpdateError {
code: UpdateErrorCode;
message: string;
details?: unknown;
}

You catch them like any other promise rejection:

import { NativeUpdate, UpdateErrorCode } from 'native-update';

try {
await NativeUpdate.sync();
} catch (e) {
const err = e as { code: UpdateErrorCode; message: string };
switch (err.code) {
case UpdateErrorCode.NETWORK_ERROR:
retryLater();
break;
case UpdateErrorCode.SIGNATURE_ERROR:
reportToSentry(err);
break;
default:
logUnknown(err);
}
}

Network errors​

CodeWire valueWhenRemediation
NETWORK_ERROR'NETWORK_ERROR'DNS failure, no internet, captive portal, TLS handshake failureRetry with exponential backoff. Fail open to "no update available" — do not block the user.
SERVER_ERROR'SERVER_ERROR'Update server returned 5xxRetry; alert your monitoring on persistent 5xx.
TIMEOUT_ERROR'TIMEOUT_ERROR'Default timeout exceededIncrease downloadTimeout in PluginInitConfig or move to BACKGROUND strategy so a long download does not block the foreground.

Download errors​

CodeWire valueWhenRemediation
DOWNLOAD_ERROR'DOWNLOAD_ERROR'Generic download failure (TLS aborted, premature close, content-length mismatch)Retry; if persistent, check server logs for connection-level issues.
STORAGE_ERROR'STORAGE_ERROR'Cannot write to the app sandbox (full disk, permission revoked)Call delete() to free old bundles; surface a "low storage" UI to the user.
SIZE_LIMIT_EXCEEDED'SIZE_LIMIT_EXCEEDED'Bundle exceeds maxBundleSize config or platform-imposed cellular capSlim the bundle; raise maxBundleSize only if you have validated the bundle is honestly that large.

Security errors​

These are the codes you should treat as alerts — they often indicate either misconfiguration or active tampering attempts.

CodeWire valueWhenRemediation
VERIFICATION_ERROR'VERIFICATION_ERROR'Umbrella — verification failed but the SDK could not pinpoint which stepInspect error.details for the specific step.
CHECKSUM_ERROR'CHECKSUM_ERROR'Computed checksum did not match expectedThe bundle was modified after signing. Re-sign and re-upload. Investigate intermediate caches / proxies.
SIGNATURE_ERROR'SIGNATURE_ERROR'Public key did not verify the signature over the checksumConfirm the public key in LiveUpdateConfig.publicKey matches the private key used by the CLI bundle sign step.
INSECURE_URL'INSECURE_URL'HTTP (not HTTPS) URL passed to a download methodUse HTTPS. iOS App Transport Security would block plain HTTP anyway.
INVALID_CERTIFICATE'INVALID_CERTIFICATE'TLS certificate failed pinning check or chain validationRenew + re-pin. See Certificate pinning.
PATH_TRAVERSAL'PATH_TRAVERSAL'Bundle ZIP contained an entry that resolves outside the install directory (e.g. ../../etc/passwd)Treat as adversarial — alert your monitoring. The bundle is rejected before any byte is written.

Installation errors​

CodeWire valueWhenRemediation
INSTALL_ERROR'INSTALL_ERROR'Could not write the bundle into place after download (filesystem race, atomic-rename failure)Retry. If persistent, file an issue with error.details.
ROLLBACK_ERROR'ROLLBACK_ERROR'Rollback to the previous bundle failedRare. Usually requires a binary reinstall from the App Store / Play Store to recover. Surface a "Please reinstall the app" dialog.
VERSION_MISMATCH'VERSION_MISMATCH'Bundle's declared version did not match the version field returned by the serverThe server lied or your build step is out of sync. Check your CI signing flow.

Permission errors​

CodeWire valueWhenRemediation
PERMISSION_DENIED'PERMISSION_DENIED'OS denied a required permission (notifications, exact alarms, etc.)Inspect error.details for which permission. Render a rationale UI before re-prompting.

App-update errors (App Store / Play Store flows)​

CodeWire valueWhenRemediation
UPDATE_NOT_AVAILABLE'UPDATE_NOT_AVAILABLE'Calling complete / immediate before a download existsAlways gate behind getAppUpdateInfo() + appUpdateReady event.
UPDATE_IN_PROGRESS'UPDATE_IN_PROGRESS'Triggering a second flow before the first completesInspect info.installStatus; wait for INSTALLED / FAILED.
UPDATE_CANCELLED'UPDATE_CANCELLED'User declined the Play promptSurface a non-blocking banner; respect their choice for the session.
PLATFORM_NOT_SUPPORTED'PLATFORM_NOT_SUPPORTED'Calling Android-only methods on iOS / web; calling a method on Huawei without GMSBranch on Capacitor.getPlatform() and feature-detect via getAppUpdateInfo() flags.

App-review errors​

CodeWire valueWhenRemediation
REVIEW_NOT_SUPPORTED'REVIEW_NOT_SUPPORTED'Play Services missing (Huawei, F-Droid, no-GMS Android), iOS without StoreKit, web without webReviewUrlFall back to opening webReviewUrl in a browser.
QUOTA_EXCEEDED'QUOTA_EXCEEDED'Some platforms surface this when their internal cap is exhaustedSkip silently; quota resets eventually.
CONDITIONS_NOT_MET'CONDITIONS_NOT_MET'Plugin-side throttle blocked the call (minimumDaysSinceInstall, etc.)Skip silently; respect the throttle.

Configuration errors​

CodeWire valueWhenRemediation
INVALID_CONFIG'INVALID_CONFIG'Required field missing in any config block, or value out of rangeInspect error.message — it identifies the offending field.
NOT_CONFIGURED'NOT_CONFIGURED'Method called before initialize() resolvedAwait initialize() before any other call. Use the isInitialized() check in defensive code.

Catch-all​

CodeWire valueWhenRemediation
UNKNOWN_ERROR'UNKNOWN_ERROR'A failure the SDK could not classify into one of the codes aboveTreat as a bug — log error.details and file an issue.

Mapping to Error classes (power users)​

The plugin also exports concrete error classes for instanceof checks:

import {
NativeUpdateError, // base class
ConfigurationError, // INVALID_CONFIG, NOT_CONFIGURED
DownloadError, // DOWNLOAD_ERROR, NETWORK_ERROR, TIMEOUT_ERROR, STORAGE_ERROR
ValidationError, // CHECKSUM_ERROR, SIGNATURE_ERROR, VERIFICATION_ERROR, PATH_TRAVERSAL, VERSION_MISMATCH
StorageError, // STORAGE_ERROR, SIZE_LIMIT_EXCEEDED
UpdateErrorClass, // alias for the base class kept for backwards compat
} from 'native-update';

try {
await NativeUpdate.sync();
} catch (e) {
if (e instanceof ValidationError) {
// signature / checksum / path-traversal — alert
} else if (e instanceof DownloadError) {
// network — retry
}
}

Both styles work — the code field is always populated even on instances of the typed classes.


Error code catalogue verified against src/definitions.ts in the plugin repo as of 2026-05-11. Documented by the Native Update team.