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
- Always provide a concrete local file Uri as the second argument of UCrop.of (e.g. Uri.fromFile(new File(getCacheDir(), "crop_temp.jpg"))).
- Pre-download the remote image to local storage yourself, then pass the local file Uri as the source.
- Null-check the destination Uri before starting uCrop and fail fast with a user-visible message.
- 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
- Always supply a local file Uri as the uCrop output, especially for http(s) sources.
- Resolve remote URLs and destination paths before calling UCrop.of, not asynchronously after.
- Register download progress/result handling via UCropFragmentCallback when using the fragment flow.
- Keep temporary download files in getCacheDir and clean them up after cropping.
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
- Output Uri is null - cannot copy image
- OutputStream for given output Uri is null
- Invalid Uri scheme%s
- InputStream for given input Uri is null
- Index [selectedByDefault = %d] (0-based) cannot be higher or
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/4a32c164afe27eec.
Report an issue: GitHub.