apache/cordova-android · error · CordovaError

One of the following attributes are set but missing the othe

Error message

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.

What it means

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.

Source

Thrown at lib/prepare.js:701

            ) {
                errorLegacyIconNeeded.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));
            } else if (!icon.src) {
                icons[key].src = icon.foreground;
            }
        }
    });

    const errorMessage = [];
    if (errorMissingAttributes.length > 0) {
        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.');
    }

    if (errorLegacyIconNeeded.length > 0) {
        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.');
    }

    if (errorMessage.length > 0) {
        throw new CordovaError(errorMessage.join(' '));
    }

    let resourceMap = Object.assign(
        {},
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.png'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_monochrome.xml'),
        mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
    );

    const preparedIcons = prepareIcons(icons);

    if (hasAdaptive) {
        resourceMap = updateIconResourceForAdaptive(preparedIcons, resourceMap, platformResourcesDir);

View on GitHub (pinned to 7c1e190064)

Solutions

  1. For every <icon> that declares background or foreground, declare BOTH: <icon background="@color/iconBg" foreground="res/icon fg.png" density="xxxhdpi"/>
  2. 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"
  3. Simplest repair: use plain raster icons only — <icon src="res/android/icon-xxxhdpi.png" density="xxxhdpi"/> — dropping background/foreground entirely
  4. Re-run `cordova prepare android` to confirm the icons pass validation before building

Example fix

<!-- before -->
<platform name="android">
  <icon background="@color/iconBackground" />
  <icon foreground="res/icon-adaptive-foreground.xml" />
</platform>

<!-- after -->
<platform name="android">
  <icon background="@color/iconBackground" foreground="res/icon-adaptive-foreground.xml" src="res/icon-adaptive-foreground-fallback.png" />
</platform>
Defensive patterns

Strategy: validation

Validate before calling

// validate config.xml icons before prepare
const icons = parseConfigIcons(); // [{src, background, foreground, density}]
const bad = icons.filter(i =>
  (!!i.background !== !!i.foreground) ||
  (!i.background && !i.foreground && !i.src) ||
  (i.foreground && !i.src && (/^@color/.test(i.foreground) || i.foreground.endsWith('.xml')))
);
if (bad.length) throw new Error('icon config invalid: ' + bad.map(i => i.density).join(', '));

Try / catch

try { await cordova.prepare('android'); } catch (e) {
  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 */ }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of apache/cordova-android@7c1e190064 (2026-08-22). Data as JSON: /api/errors/447d517e7cbffea8. Report an issue: GitHub.