Troubleshooting Common Issues
Solutions to problems encountered during macOS app releases.
Version Issues
Version Not Updating After Rebuild
Symptom: After updating version and rebuilding, the app still shows the old version:
defaults read APP.app/Contents/Info.plist CFBundleShortVersionString
# Shows: 1.0.8 (expected: 1.0.9)Cause: The version is defined in an .xcconfig file, not directly in project.pbxproj or Info.plist.
Solution:
Find the version configuration file:
find . -name "*.xcconfig" -type f | grep -v DerivedDataUpdate APP_VERSION in the .xcconfig file:
APP_VERSION = 1.0.9Verify the project uses this value:
grep -r "MARKETING_VERSION.*APP_VERSION" *.xcodeproj/project.pbxprojRebuild from scratch:
rm -rf ~/Desktop/APP-VERSION.xcarchive xcodebuild -project PROJECT.xcodeproj -scheme SCHEME \ -configuration Release -archivePath ~/Desktop/APP-VERSION.xcarchive archiveVerify the version in the new archive:
defaults read ~/Desktop/APP-VERSION.xcarchive/Products/Applications/APP.app/Contents/Info.plist CFBundleShortVersionString
Prevention: Always update the version in the .xcconfig file, not just Info.plist.
agvtool Not Working
Symptom: Running agvtool new-marketing-version appears to work but version doesn't change.
Cause: The project uses .xcconfig files for version management, which agvtool doesn't handle.
Solution: Manually edit the .xcconfig file instead of using agvtool.
Code Signing Issues
Sparkle Framework Not Signed
Symptom: Notarization fails with errors about unsigned Sparkle binaries:
{
"severity": "error",
"path": "Claw.app/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.app",
"message": "The binary is not signed with a valid Developer ID certificate."
}Cause: Copying the app directly from the .xcarchive without proper export doesn't sign embedded frameworks.
Solution: Use xcodebuild -exportArchive instead of copying:
# Wrong: Copying from archive
cp -R ~/Desktop/APP.xcarchive/Products/Applications/APP.app ~/Desktop/APP-Export/
# Correct: Export with signing
xcodebuild -exportArchive \
-archivePath ~/Desktop/APP.xcarchive \
-exportPath ~/Desktop/APP-Export \
-exportOptionsPlist ExportOptions.plistVerification:
codesign -dvvv ~/Desktop/APP-Export/APP.app/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.appShould show "Developer ID Application" in Authority lines.
Missing Secure Timestamp
Symptom: Notarization log shows:
{
"severity": "error",
"message": "The signature does not include a secure timestamp."
}Cause: Manual signing or copying files without proper export process.
Solution: Always use xcodebuild -exportArchive which automatically includes timestamps.
DMG Issues
DMG Missing Applications Folder
Symptom: DMG opens but there's no Applications folder for drag-and-drop installation.
Cause: Created DMG with simple hdiutil create without creating symlink.
Solution: Create temporary directory with symlink before creating DMG:
TEMP_DMG_DIR="/tmp/APP_dmg" && \
rm -rf "${TEMP_DMG_DIR}" && \
mkdir -p "${TEMP_DMG_DIR}" && \
cp -R ~/Desktop/APP-Export/APP.app "${TEMP_DMG_DIR}/" && \
ln -s /Applications "${TEMP_DMG_DIR}/Applications" && \
hdiutil create -volname "APP VERSION" \
-srcfolder "${TEMP_DMG_DIR}" \
-ov -format UDZO ~/Desktop/APP.dmg && \
rm -rf "${TEMP_DMG_DIR}"Verification:
hdiutil attach ~/Desktop/APP.dmg -readonly -nobrowse -mountpoint /tmp/verify && \
ls -la /tmp/verify && \
hdiutil detach /tmp/verifyShould show both APP.app and Applications -> /Applications symlink.
DMG Creation Fails "Operation Not Permitted"
Symptom:
hdiutil: create failed - Operation not permittedCause: Another DMG is already mounted at the same volume name.
Solution: Unmount any existing volumes:
hdiutil detach /Volumes/APP* 2>/dev/null || trueThen create DMG again.
Notarization Issues
"Malicious Software" Warning When Opening App
Symptom: macOS shows warning: "APP is damaged and can't be opened. You should move it to the Trash."
Cause: App is signed but not notarized.
Check notarization status:
spctl -a -vvv /Applications/APP.appIf shows "Unnotarized Developer ID":
- Submit app for notarization
- Wait for acceptance
- Staple the ticket
Full process:
# Submit
xcrun notarytool submit APP.dmg \
--apple-id EMAIL --team-id TEAM_ID --password PASSWORD --wait
# Staple
xcrun stapler staple APP.dmg
# Verify
spctl -a -vvv APP.app
# Should show: "Notarized Developer ID"Notarization Invalid - Multiple Errors
Symptom: Notarization fails with many errors about embedded frameworks.
Cause: App wasn't properly exported with code signing.
Solution:
Delete existing export:
rm -rf ~/Desktop/APP-ExportCreate proper ExportOptions.plist:
cat > /tmp/ExportOptions.plist << 'EOF' <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>destination</key> <string>export</string> <key>method</key> <string>developer-id</string> <key>signingStyle</key> <string>automatic</string> <key>teamID</key> <string>YOUR_TEAM_ID</string> <key>signingCertificate</key> <string>Developer ID Application</string> </dict> </plist> EOFExport properly:
xcodebuild -exportArchive \ -archivePath ~/Desktop/APP.xcarchive \ -exportPath ~/Desktop/APP-Export \ -exportOptionsPlist /tmp/ExportOptions.plistTry notarization again
Notarization Credentials Rejected
Symptom:
Error: HTTP status code: 401. Invalid credentials.Common causes:
Wrong Apple ID email
- Verify at https://developer.apple.com/account
- Must be the email associated with Developer ID certificate
Expired app-specific password
- Generate new one at https://appleid.apple.com
- Under "Sign-In and Security" → "App-Specific Passwords"
Wrong team ID
- Find at https://developer.apple.com/account
- Under "Membership" → "Team ID"
Typo in credentials
- Double-check each value
- App-specific password format:
xxxx-xxxx-xxxx-xxxx
Sparkle Update Issues
Signature Doesn't Match
Symptom: Users report update downloads but fails to install with signature error.
Cause: The EdDSA signature in appcast.xml doesn't match the actual zip file.
Common scenarios:
- Updated appcast.xml before rebuilding
- Rebuilt app but didn't update signature
- Modified zip after signing
Solution:
- Rebuild app
- Create NEW zip:
cd ~/Desktop/APP-Export rm -f APP.app.zip ditto -c -k --keepParent APP.app APP.app.zip - Generate NEW signature:
echo "PRIVATE_KEY" | sign_update APP.app.zip --ed-key-file - - Update appcast.xml with NEW signature and size
- Test locally before pushing
Updates Not Detected
Symptom: Sparkle doesn't show update notification for new version.
Checklist:
Verify appcast.xml is accessible:
curl -I https://raw.githubusercontent.com/USER/REPO/main/appcast.xml # Should return 200 OKCheck version comparison:
# Current version in app defaults read /Applications/APP.app/Contents/Info.plist CFBundleShortVersionString # Compare with <sparkle:version> in appcast.xmlVerify XML syntax:
xmllint --noout appcast.xml # Should show no errorsCheck public key matches:
# Public key in app defaults read /Applications/APP.app/Contents/Info.plist SUPublicEDKey # Should match the key used to generate signature
Signature Changes After Each Build
Symptom: Every rebuild produces a different EdDSA signature, even for the same version.
Cause: This is expected behavior. Signatures include build timestamps and UUIDs.
Solution: This is normal. Always:
- Do final build
- Generate signature from that build
- Update appcast.xml with that signature
- Don't rebuild after generating signature
If you must rebuild, regenerate the signature.
GitHub Release Issues
CI Fails on Release Commit
Symptom: GitHub Actions fails after pushing release commit.
Cause: CI environment doesn't have your Developer ID certificate (expected for local builds).
Expected behavior: CI failures are normal for local release builds. The release workflow is:
- Build locally (with your certificate)
- Export and sign locally
- Upload to GitHub releases
- CI may fail - ignore it for release commits
Solution: This is expected. Either:
- Add
[skip ci]to commit message - Configure CI to skip release commits
- Accept that CI fails for release commits
Tag Naming Inconsistency
Symptom: appcast.xml URL doesn't match actual release tag, causing 404 errors.
Cause: Some releases use v prefix (v1.2.4) and some don't (1.3.3).
Solution: Check your existing releases and use consistent naming:
# Check existing tags
gh release list --limit 5
# Match URL format in appcast.xml to your tag format
# If tags are v1.2.4: url=".../download/v1.2.4/APP.app.zip"
# If tags are 1.2.4: url=".../download/1.2.4/APP.app.zip"Best practice: Pick one format and stick with it for all releases.
Assets Not Uploading
Symptom: gh release upload fails or times out.
Common causes:
File doesn't exist:
ls -lh ~/Desktop/APP.dmg ls -lh ~/Desktop/APP-Export/APP.app.zipGitHub CLI not authenticated:
gh auth statusRelease tag doesn't exist:
gh release view vVERSIONNetwork timeout:
- Retry the upload
- Check file size (very large files may timeout)
Solution:
# Ensure files exist
ls -lh ~/Desktop/APP-1.0.9.dmg ~/Desktop/APP-1.0.9-Export/APP.app.zip
# Re-authenticate if needed
gh auth login
# Upload with explicit paths
gh release upload v1.0.9 \
~/Desktop/APP-1.0.9.dmg \
~/Desktop/APP-1.0.9-Export/APP.app.zip \
--clobberTesting Issues
Downloaded App Shows Wrong Version
Symptom: After downloading DMG from GitHub, installed app shows wrong version.
Cause: Cached app or DMG wasn't updated.
Solution:
Remove all existing installations:
rm -rf /Applications/APP.app rm -rf ~/Library/Preferences/BUNDLE_ID.plist rm -rf ~/Library/Caches/BUNDLE_IDDownload fresh DMG from GitHub
Verify DMG version before installing:
hdiutil attach APP.dmg -readonly -nobrowse -mountpoint /tmp/test defaults read /tmp/test/APP.app/Contents/Info.plist CFBundleShortVersionString hdiutil detach /tmp/testInstall and verify:
cp -R /tmp/test/APP.app /Applications/ defaults read /Applications/APP.app/Contents/Info.plist CFBundleShortVersionString
Quick Diagnostic Commands
Check version in built app:
defaults read ~/Desktop/APP-Export/APP.app/Contents/Info.plist CFBundleShortVersionStringCheck code signing:
codesign -dvvv ~/Desktop/APP-Export/APP.app 2>&1 | grep -E "Authority|TeamIdentifier"Check notarization:
spctl -a -vvv ~/Desktop/APP-Export/APP.appVerify DMG contents:
hdiutil attach APP.dmg -readonly -nobrowse -mountpoint /tmp/check && \
ls -la /tmp/check && \
hdiutil detach /tmp/checkCheck Sparkle framework signing:
codesign -dvvv ~/Desktop/APP-Export/APP.app/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.appVerify appcast.xml accessible:
curl -I https://raw.githubusercontent.com/USER/REPO/main/appcast.xmlTest XML syntax:
xmllint --noout appcast.xmlGetting Help
If you're still stuck:
Collect diagnostic information:
- Version of Xcode
- macOS version
- Output of diagnostic commands above
- Notarization logs (if applicable)
Check Sparkle documentation:
Review Apple notarization docs:
Common issue trackers:
- Sparkle issues: https://github.com/sparkle-project/Sparkle/issues
- Xcode signing issues: https://developer.apple.com/forums/