Troubleshooting and Incident Resolution Guide
This guide compiles field-tested solutions for diagnosing and resolving cross-cutting anomalies across the TkushPatch platform.
1. CLI and Compilation Anomalies
Error: shorebird.yaml not found or Missing app_id
- Symptom: Running
tk-ota-push releaseortk-ota-push patchaborts with an error indicating a missing configuration manifest. - Root Cause: The command is executing from a nested subfolder or the project was never initialized.
- Resolution:
- Navigate to the root directory containing
pubspec.yaml. - Run
tk-ota-push initto regenerateshorebird.yaml. - Ensure both mandatory properties are present:
app_id: "YOUR-APP-UUID"
base_url: "https://api.tkushpatch.domain.com"
- Navigate to the root directory containing
Error: Patch rejected: Native code modified (native_bridge_ok: false)
- Symptom: The
tk-ota-push patchcommand halts, flagging alterations to native platform code. - Root Cause: Dependencies added to
pubspec.yamlintroduce C++, Java/Kotlin, or Objective-C/Swift native source files absent from the Store release. - Resolution:
- An OTA patch can only deliver pure Dart code.
- If you introduced native plugins (e.g., a hardware camera or BLE library), you must compile a new baseline Store release (
tk-ota-push release android) and submit it to marketplace review.
2. Distribution and Patch Lifecycle Issues
Symptom: The patch is published but devices do not download it
Work systematically through these 5 common checks:
Troubleshooting Decision Flow
- Patch status is
STAGED? ➔ Go to Approvals in Web Console to review and approve the patch. - Patch status is
ROLLED_BACK? ➔ Update was revoked. Publish a new incremental patch number. - Device does not receive update? ➔ Check device channel, targeted countries, and active rollout percentage.
HTTP 429 Too Many Requests
- Symptom: Handsets receive an HTTP 429 status code with a
Retry-After: 60response header. - Root Cause: The Token Bucket Rate-Limiter (
DataPlaneRateLimitFilter) detected more than 120 requests/minute from the client IP address. - Resolution:
- If mobile devices share a centralized corporate egress proxy, increase the capacity threshold and trust proxy headers in
application.properties:ota.rate-limit.trust-forwarded-header=true
ota.rate-limit.capacity-per-minute=300
- If mobile devices share a centralized corporate egress proxy, increase the capacity threshold and trust proxy headers in
3. Cryptography and cryptographic signing engine Signer
Error: RSA signature verification failed (ring::error::Unspecified)
- Symptom: The mobile handset downloads the patch but rejects it, logging a verification failure in
adb logcator Xcode Console. - Root Cause 1: The public key baked into the initial Store release binary does not match the private key used to sign the patch.
- Verification: Did you build the APK with a different account or point to a non-production environment key?
- Root Cause 2: Signature payload mismatch. The server must sign the 64-character lowercase ASCII representation of the SHA-256 digest (
hash.toLowerCase().getBytes(US_ASCII)), not the raw binary bytes.
Console Error: Signing Service Unavailable (HTTP 503)
- Symptom: Approving or signing patches on
/approvalsfails with a 503 Service Unavailable alert. - Root Cause: The cryptographic signing engine container restarted and returned to the initial sealed state.
- Resolution:
- Access the signing engine cluster via SSH or admin terminal.
- Submit your Shamir unseal quorum: Contact your system administrator to reactivate the signing service.
- Once
sealed: false, reload the web console to resume signing operations.
4. Mobile Runtime Behavior and Crash Recovery
Symptom: The patch downloads successfully but changes do not appear
- Root Cause: By default, the Flutter runtime activates downloaded patches upon the next cold restart of the application to prevent jarring runtime state loss.
- Resolution:
- Terminate the app completely (swipe it away from the OS multitasking switcher).
- Relaunch it. The update should execute immediately.
- To enforce an immediate in-session restart, invoke
TkOtaPush.restartApp()from the SDK within a custom blocking update dialog.
Symptom: Application crashes at startup and reverts to older code
- Root Cause: TkushPatch's native 2-Crash Rollback Guard caught an unhandled fatal exception on consecutive startup cycles.
- Diagnostic Steps:
- Navigate to
/symbols. - Capture the crash stack trace from device logs or your APM reporter.
- Paste the obfuscated stack trace into the deobfuscation tool to pinpoint the offending source line:
#00 abs 00000072a3194 application binary + 0x12a3194
=> package:my_app/services/api_service.dart:42:15 in fetchData() - Fix the Dart exception in code and publish a replacement
Patch #2.
- Navigate to