{"record":{"id":"19fc9bf5e980e076","repo":"apache/cordova-android","slug":"keystore-file-does-not-exist-storefile-getabsol","errorCode":null,"errorMessage":"Keystore file does not exist: ${storeFile.getAbsolutePath()}","messagePattern":"Keystore file does not exist: (.+?)","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"templates/project/app/build.gradle","lineNumber":344,"sourceCode":"    // SUB-PROJECT DEPENDENCIES START\n    debugCompile(project(path: \":CordovaLib\", configuration: \"debug\"))\n    releaseCompile(project(path: \":CordovaLib\", configuration: \"release\"))\n    // SUB-PROJECT DEPENDENCIES END\n}\n\ndef addSigningProps(propsFilePath, signingConfig) {\n    def propsFile = file(propsFilePath)\n    def props = new Properties()\n    propsFile.withReader { reader ->\n        props.load(reader)\n    }\n\n    def storeFile = new File(props.get('key.store') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'storeFile'))\n    if (!storeFile.isAbsolute()) {\n        storeFile = RelativePath.parse(true, storeFile.toString()).getFile(propsFile.getParentFile())\n    }\n    if (!storeFile.exists()) {\n        throw new FileNotFoundException('Keystore file does not exist: ' + storeFile.getAbsolutePath())\n    }\n    signingConfig.keyAlias = props.get('key.alias') ?: privateHelpers.ensureValueExists(propsFilePath, props, 'keyAlias')\n    signingConfig.keyPassword = props.get('keyPassword', props.get('key.alias.password', signingConfig.keyPassword))\n    signingConfig.storeFile = storeFile\n    signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword))\n    def storeType = props.get('storeType', props.get('key.store.type', ''))\n    if (!storeType) {\n        def filename = storeFile.getName().toLowerCase()\n        if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {\n            storeType = 'pkcs12'\n        } else {\n            storeType = signingConfig.storeType // \"jks\"\n        }\n    }\n    signingConfig.storeType = storeType\n}\n\nfor (def func : cdvPluginPostBuildExtras) {","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/apache/cordova-android/blob/7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3/templates/project/app/build.gradle#L326-L362","documentation":"addSigningProps runs for the debug and release signing configs whenever a signing properties file is in play — platforms/android/debug-signing.properties / release-signing.properties (the template falls back to ../release-signing.properties from the app module) or a path passed via the cdvReleaseSigningPropertiesFile / cdvDebugSigningPropertiesFile gradle properties (set by the cordova CLI when you build with --keystore flags). It reads key.store (or storeFile) and, crucially, resolves RELATIVE paths against the properties file's parent directory (platforms/android/), not the repo root or the shell's cwd. If the resolved file does not exist, it throws FileNotFoundException showing the exact absolute path it checked.","triggerScenarios":"A relative keystore path that assumes the repo root but gets resolved against platforms/android/; the keystore was moved, renamed, or deleted after the signing properties were generated; CI checkout that never placed the keystore (secret/base64 decode step failed or ran after gradle); an absolute path from another machine (e.g. a macOS path on a Linux runner).","commonSituations":"cordova build android --release --keystore=../myapp.keystore run later from a different working directory; keystores kept outside the repo so every machine needs its own path; CI secrets step failing silently before the build stage; team members sharing release-signing.properties with machine-specific paths.","solutions":["Look at the absolute path in the message — that is exactly where gradle looked. Either place the keystore there or fix the path in the properties file to point at the real file.","Remember the resolution base: relative key.store / storeFile values resolve against the directory containing the .properties file (platforms/android/), so a repo-root keystore needs ../../myapp.keystore — or better, an absolute path.","In CI, verify the keystore placement step (base64 decode / download) actually produced the file before gradle runs.","Regenerate the signing configuration in one consistent shot: cordova build android --release --keystore=/abs/path/to/app.keystore --alias=... so the CLI rewrites the properties file with the value you pass."],"exampleFix":"# before — platforms/android/release-signing.properties\nkey.store=my-release-key.keystore\n# gradle looks at platforms/android/my-release-key.keystore (missing — file is at repo root)\n\n# after\nkey.store=../../my-release-key.keystore\n# or absolute:\nkey.store=/home/me/keys/my-release-key.keystore","handlingStrategy":"validation","validationCode":"# Resolve the keystore exactly like addSigningProps does (relative to the .properties file) and check it exists\nPROPS=platforms/android/release-signing.properties\nSTORE=$(sed -n 's/^key\\.store=//p' \"$PROPS\" | head -1)\n[ -z \"$STORE\" ] && STORE=$(sed -n 's/^storeFile=//p' \"$PROPS\" | head -1)\ncase \"$STORE\" in\n  /*) F=\"$STORE\" ;;\n  *)  F=\"$(cd \"$(dirname \"$PROPS\")\"/\"$(dirname \"$STORE\")\" && pwd)/$(basename \"$STORE\")\" ;;\nesac\n[ -f \"$F\" ] || { echo \"Keystore missing at $F — fix the path in $PROPS or place the file\"; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute keystore paths in CI signing properties; use ../../ relative paths only if the file lives inside the repo.","Remember the resolution base is the directory of the .properties file (platforms/android/), not the repo root or cwd.","Make the CI step that decodes/downloads the keystore a hard dependency of the build step, and assert the file exists in between.","Generate signing properties with one consistent cordova build --release --keystore=... invocation instead of editing files across machines."],"tags":["signing","keystore","release-build","gradle","android"],"backgroundTag":"missing-keystore-file","analyzedSha":"7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3","analyzedAt":"2026-08-22T04:57:58.868Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}