material-components/material-components-android · error · IllegalArgumentException

invalid shadow size

Error message

invalid shadow size

What it means

ShadowDrawableWrapper.setShadowSize(float, float) throws IllegalArgumentException when either the shadow size or the max shadow size is negative. Sizes are rounded to even pixel values for symmetric shadow rendering; negative dimensions would invert the shadow geometry, so they are rejected immediately.

Source

Thrown at lib/java/com/google/android/material/shadow/ShadowDrawableWrapper.java:127

    this.addPaddingForCorners = addPaddingForCorners;
    invalidateSelf();
  }

  @Override
  public void setAlpha(int alpha) {
    super.setAlpha(alpha);
    cornerShadowPaint.setAlpha(alpha);
    edgeShadowPaint.setAlpha(alpha);
  }

  @Override
  protected void onBoundsChange(Rect bounds) {
    dirty = true;
  }

  public void setShadowSize(float shadowSize, float maxShadowSize) {
    if (shadowSize < 0 || maxShadowSize < 0) {
      throw new IllegalArgumentException("invalid shadow size");
    }
    shadowSize = toEven(shadowSize);
    maxShadowSize = toEven(maxShadowSize);
    if (shadowSize > maxShadowSize) {
      shadowSize = maxShadowSize;
      if (!printedShadowClipWarning) {
        printedShadowClipWarning = true;
      }
    }
    if (rawShadowSize == shadowSize && rawMaxShadowSize == maxShadowSize) {
      return;
    }
    rawShadowSize = shadowSize;
    rawMaxShadowSize = maxShadowSize;
    this.shadowSize = Math.round(shadowSize * SHADOW_MULTIPLIER);
    this.maxShadowSize = maxShadowSize;
    dirty = true;
    invalidateSelf();

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Clamp values before the call: setShadowSize(Math.max(0, shadowSize), Math.max(0, maxShadowSize)).
  2. Fix the arithmetic producing the negative value (check dp * density math and interpolation bounds).
  3. If animating shadow size, animate within [0, target] and use an interpolator/clamp that cannot overshoot below 0.

Example fix

// before
wrapper.setShadowSize(currentElevation - removedElevation, maxShadow);

// after
wrapper.setShadowSize(Math.max(0f, currentElevation - removedElevation), Math.max(0f, maxShadow));
Defensive patterns

Strategy: validation

Validate before calling

float clamped = Math.max(0f, computedShadowSize);
float clampedMax = Math.max(clamped, Math.max(0f, computedMaxShadowSize));
wrapper.setShadowSize(clamped, clampedMax);

Prevention

When it happens

Trigger: Calling setShadowSize() (directly or via CardView-style elevation helpers) with a negative dp-to-px conversion — e.g. multiplying by a negative density, passing -elevation, or an arithmetic bug that yields < 0.

Common situations: Computing shadow size from a difference like (margin - padding) that can go negative on dense/small screens; interpolating shadow size toward 0 and overshooting slightly below zero; passing raw negative float state values (e.g. scroll offset) as elevation.

Related errors


AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14). Data as JSON: /api/errors/982655211a31133d. Report an issue: GitHub.