{"record":{"id":"447d517e7cbffea8","repo":"apache/cordova-android","slug":"one-of-the-following-attributes-are-set-but-missin","errorCode":null,"errorMessage":"One of the following attributes are set but missing the other for the density type: ${errorMissingAttributes.join(', ')}. Please ensure that all require attributes are defined. For the following icons with the density of: ${errorLegacyIconNeeded.join(', ')}, adaptive foreground with a defined color or vector can not be used as a standard fallback icon for older Android devices. To support older Android environments, please provide a value for the src attribute.","messagePattern":"One of the following attributes are set but missing the other for the density type: (.+?)\\. Please ensure that all require attributes are defined\\. For the following icons with the density of: (.+?), adaptive foreground with a defined color or vector can not be used as a standard fallback icon for older Android devices\\. To support older Android environments, please provide a value for the src attribute\\.","errorType":"validation","errorClass":"CordovaError","httpStatus":null,"severity":"error","filePath":"lib/prepare.js","lineNumber":701,"sourceCode":"            ) {\n                errorLegacyIconNeeded.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));\n            } else if (!icon.src) {\n                icons[key].src = icon.foreground;\n            }\n        }\n    });\n\n    const errorMessage = [];\n    if (errorMissingAttributes.length > 0) {\n        errorMessage.push('One of the following attributes are set but missing the other for the density type: ' + errorMissingAttributes.join(', ') + '. Please ensure that all require attributes are defined.');\n    }\n\n    if (errorLegacyIconNeeded.length > 0) {\n        errorMessage.push('For the following icons with the density of: ' + errorLegacyIconNeeded.join(', ') + ', adaptive foreground with a defined color or vector can not be used as a standard fallback icon for older Android devices. To support older Android environments, please provide a value for the src attribute.');\n    }\n\n    if (errorMessage.length > 0) {\n        throw new CordovaError(errorMessage.join(' '));\n    }\n\n    let resourceMap = Object.assign(\n        {},\n        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.png'),\n        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),\n        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),\n        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.png'),\n        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),\n        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),\n        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.xml'),\n        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.xml')\n    );\n\n    const preparedIcons = prepareIcons(icons);\n\n    if (hasAdaptive) {\n        resourceMap = updateIconResourceForAdaptive(preparedIcons, resourceMap, platformResourcesDir);","sourceCodeStart":683,"sourceCodeEnd":719,"githubUrl":"https://github.com/apache/cordova-android/blob/7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3/lib/prepare.js#L683-L719","documentation":"During `cordova prepare android`, updateIcons validates every <icon> in config.xml for the android platform and throws this combined CordovaError when (a) an icon sets background without foreground or vice versa (or sets neither plus no src), and/or (b) an adaptive icon's foreground is a @color reference or vector .xml while no legacy src is provided. Adaptive (API 26+) icons need both layers, and pre-API-26 devices need a raster src fallback.","triggerScenarios":"Running `cordova build android` / `cordova prepare` with config.xml like <icon background=\"@color/iconBg\"/> (no foreground), or <icon foreground=\"res/icon.xml\"/> where icon.xml is a vector and there is no src=\"...png\" icon for that density. The first loop in updateIcons collects errorMissingAttributes and errorLegacyIconNeeded and throws at prepare time.","commonSituations":"Copying adaptive-icon config from a blog post but dropping the src fallback; migrating an app that only defines foreground+background expecting Android to synthesize the legacy icon; using @color backgrounds introduced for adaptive icons on an old template; density attributes (ldpi..xxxhdpi) partially updated.","solutions":["For every <icon> that declares background or foreground, declare BOTH: <icon background=\"@color/iconBg\" foreground=\"res/icon fg.png\" density=\"xxxhdpi\"/>","For adaptive icons whose foreground is @color/... or a vector .xml, add a legacy raster fallback on the same element: src=\"res/icon-xxxhdpi.png\"","Simplest repair: use plain raster icons only — <icon src=\"res/android/icon-xxxhdpi.png\" density=\"xxxhdpi\"/> — dropping background/foreground entirely","Re-run `cordova prepare android` to confirm the icons pass validation before building"],"exampleFix":"<!-- before -->\n<platform name=\"android\">\n  <icon background=\"@color/iconBackground\" />\n  <icon foreground=\"res/icon-adaptive-foreground.xml\" />\n</platform>\n\n<!-- after -->\n<platform name=\"android\">\n  <icon background=\"@color/iconBackground\" foreground=\"res/icon-adaptive-foreground.xml\" src=\"res/icon-adaptive-foreground-fallback.png\" />\n</platform>","handlingStrategy":"validation","validationCode":"// validate config.xml icons before prepare\nconst icons = parseConfigIcons(); // [{src, background, foreground, density}]\nconst bad = icons.filter(i =>\n  (!!i.background !== !!i.foreground) ||\n  (!i.background && !i.foreground && !i.src) ||\n  (i.foreground && !i.src && (/^@color/.test(i.foreground) || i.foreground.endsWith('.xml')))\n);\nif (bad.length) throw new Error('icon config invalid: ' + bad.map(i => i.density).join(', '));","typeGuard":null,"tryCatchPattern":"try { await cordova.prepare('android'); } catch (e) {\n  if (/adaptive foreground/.test(e.message) || /missing the other for the density type/.test(e.message)) { /* fix <icon> elements listed in the message, then re-prepare */ }\n}","preventionTips":["For adaptive icons always set background AND foreground AND a raster src fallback","Provide plain PNG icons per density as a safe baseline","Run `cordova prepare android` in CI to catch icon config errors early"],"tags":["cordova","cordova-android","config-xml","icons","adaptive-icons","prepare"],"backgroundTag":"config-validation-failed","analyzedSha":"7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3","analyzedAt":"2026-08-22T04:57:58.868Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}