bumptech/glide · error · IllegalArgumentException

Requested frame must be non-negative, or DEFAULT_FRAME, give

Error message

Requested frame must be non-negative, or DEFAULT_FRAME, given: {frameTimeMicros}

What it means

IllegalArgumentException thrown by VideoDecoder.decode() when the TARGET_FRAME option is set to a value that is negative and not equal to DEFAULT_FRAME (Long.MIN_VALUE). Frame times must be non-negative microseconds or the DEFAULT_FRAME sentinel.

Source

Thrown at library/src/main/java/com/bumptech/glide/load/resource/bitmap/VideoDecoder.java:177

    this.initializer = initializer;
    this.factory = factory;
  }

  @Override
  public boolean handles(@NonNull T data, @NonNull Options options) {
    // Calling setDataSource is expensive so avoid doing so unless we're actually called.
    // For non-videos this isn't any cheaper, but for videos it saves the redundant call and
    // 50-100ms.
    return true;
  }

  @Override
  public Resource<Bitmap> decode(
      @NonNull T resource, int outWidth, int outHeight, @NonNull Options options)
      throws IOException {
    long frameTimeMicros = options.get(TARGET_FRAME);
    if (frameTimeMicros < 0 && frameTimeMicros != DEFAULT_FRAME) {
      throw new IllegalArgumentException(
          "Requested frame must be non-negative, or DEFAULT_FRAME, given: " + frameTimeMicros);
    }
    Integer frameOption = options.get(FRAME_OPTION);
    if (frameOption == null) {
      frameOption = DEFAULT_FRAME_OPTION;
    }
    DownsampleStrategy downsampleStrategy = options.get(DownsampleStrategy.OPTION);
    if (downsampleStrategy == null) {
      downsampleStrategy = DownsampleStrategy.DEFAULT;
    }

    final Bitmap result;
    MediaMetadataRetriever mediaMetadataRetriever = factory.build();
    try {
      initializer.initializeRetriever(mediaMetadataRetriever, resource);
      result =
          decodeFrame(
              resource,

View on GitHub (pinned to eb14a895d8)

Solutions

  1. Use VideoDecoder.DEFAULT_FRAME instead of -1 when you want the default frame.
  2. Clamp computed frame times to >= 0 before setting the option.
  3. Validate the requested frame time against the video's duration (from MediaMetadataRetriever) before decoding.

Example fix

// before
Glide.with(ctx).asBitmap().load(videoUri)
  .set(VideoDecoder.TARGET_FRAME, durationMs - leadInMs) // can be negative
  .into(img);
// after
long frame = Math.max(0, durationMs - leadInMs);
Glide.with(ctx).asBitmap().load(videoUri)
  .set(VideoDecoder.TARGET_FRAME, frame == 0 ? VideoDecoder.DEFAULT_FRAME : frame)
  .into(img);
Defensive patterns

Strategy: validation

Validate before calling

// Clamp frame time before setting TARGET_FRAME.
long frame = requestedFrameMicros;
if (frame < 0) frame = VideoDecoder.DEFAULT_FRAME;
Glide.with(ctx).asBitmap().load(videoUri)
  .set(VideoDecoder.TARGET_FRAME, frame)
  .into(img);

Prevention

When it happens

Trigger: Setting option VideoDecoder.TARGET_FRAME to a negative long via .set(VideoDecoder.TARGET_FRAME, -1L). Also from passing a calculated negative frame offset (e.g. video duration - X where X exceeds duration).

Common situations: Trying to grab a thumbnail at a time computed from metadata where the computation underflows to a negative value. Using -1 as a 'default' sentinel instead of VideoDecoder.DEFAULT_FRAME.

Related errors


AI-assisted analysis of bumptech/glide@eb14a895d8 (2026-08-14). Data as JSON: /api/errors/545b386885018b08. Report an issue: GitHub.