Yalantis/uCrop · error · NullPointerException

Output Uri is null - cannot download image

Error message

Output Uri is null - cannot download image

What it means

BitmapLoadTask.downloadFile throws this NullPointerException when it is asked to download a remote image (http/https source Uri) but the destination output Uri is null. The download target is mandatory: without it the downloaded bytes have nowhere to go, so the task aborts before the network request.

Source

Thrown at ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java:210

            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
            }
        } finally {
            BitmapLoadUtils.close(outputStream);
            BitmapLoadUtils.close(inputStream);

            // swap uris, because input image was copied to the output destination
            // (cropped image will override it later)
            mInputUri = mOutputUri;
        }
    }

    private void downloadFile(@NonNull Uri inputUri, @Nullable Uri outputUri) throws NullPointerException, IOException {
        Log.d(TAG, "downloadFile");

        if (outputUri == null) {
            throw new NullPointerException("Output Uri is null - cannot download image");
        }

        OkHttpClient client = UCropHttpClientStore.INSTANCE.getClient();

        BufferedSource source = null;
        Sink sink = null;
        Response response = null;
        try {
            Request request = new Request.Builder()
                .url(inputUri.toString())
                .build();
            response = client.newCall(request).execute();
            source = response.body().source();

            OutputStream outputStream;

            if (isContentUri(mOutputUri)) {
                outputStream = mContext.getContentResolver().openOutputStream(outputUri);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Always provide a concrete local file Uri as the second argument of UCrop.of (e.g. Uri.fromFile(new File(getCacheDir(), "crop_temp.jpg"))).
  2. Pre-download the remote image to local storage yourself, then pass the local file Uri as the source.
  3. Null-check the destination Uri before starting uCrop and fail fast with a user-visible message.
  4. When constructing options via bundle, verify UCrop.EXTRA_OUTPUT_URI is set.

Example fix

// before
UCrop.of(Uri.parse("https://example.com/photo.jpg"), null).start(this);
// after
File dest = new File(getCacheDir(), "downloaded.jpg");
UCrop.of(Uri.parse("https://example.com/photo.jpg"), Uri.fromFile(dest)).start(this);
Defensive patterns

Strategy: validation

Validate before calling

if (destUri == null) {
    destUri = Uri.fromFile(new File(context.getCacheDir(), "ucrop_download_" + System.currentTimeMillis() + ".jpg"));
}

Type guard

boolean canDownloadTo(Uri source, Uri dest) {
    return source != null && dest != null
        && ("http".equals(source.getScheme()) || "https".equals(source.getScheme()));
}

Try / catch

try {
    UCrop.of(remoteUri, destUri).start(activity);
} catch (NullPointerException e) {
    Log.e(TAG, "Missing output Uri for download", e);
}

Prevention

When it happens

Trigger: Calling UCrop.of(httpUri, null) — or otherwise reaching downloadFile with a null output Uri — so the http(s) branch of processInputUri cannot stage the file locally.

Common situations: Loading remote images directly into uCrop while the destination path is computed asynchronously and still null; forgetting the output argument when integrating the fragment API; destination provider/file creation failed earlier and returned null silently.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/4a32c164afe27eec. Report an issue: GitHub.