{"record":{"id":"4a32c164afe27eec","repo":"Yalantis/uCrop","slug":"output-uri-is-null-cannot-download-image","errorCode":null,"errorMessage":"Output Uri is null - cannot download image","messagePattern":"Output Uri is null - cannot download image","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java","lineNumber":210,"sourceCode":"            int length;\n            while ((length = inputStream.read(buffer)) > 0) {\n                outputStream.write(buffer, 0, length);\n            }\n        } finally {\n            BitmapLoadUtils.close(outputStream);\n            BitmapLoadUtils.close(inputStream);\n\n            // swap uris, because input image was copied to the output destination\n            // (cropped image will override it later)\n            mInputUri = mOutputUri;\n        }\n    }\n\n    private void downloadFile(@NonNull Uri inputUri, @Nullable Uri outputUri) throws NullPointerException, IOException {\n        Log.d(TAG, \"downloadFile\");\n\n        if (outputUri == null) {\n            throw new NullPointerException(\"Output Uri is null - cannot download image\");\n        }\n\n        OkHttpClient client = UCropHttpClientStore.INSTANCE.getClient();\n\n        BufferedSource source = null;\n        Sink sink = null;\n        Response response = null;\n        try {\n            Request request = new Request.Builder()\n                .url(inputUri.toString())\n                .build();\n            response = client.newCall(request).execute();\n            source = response.body().source();\n\n            OutputStream outputStream;\n\n            if (isContentUri(mOutputUri)) {\n                outputStream = mContext.getContentResolver().openOutputStream(outputUri);","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java#L192-L228","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nUCrop.of(Uri.parse(\"https://example.com/photo.jpg\"), null).start(this);\n// after\nFile dest = new File(getCacheDir(), \"downloaded.jpg\");\nUCrop.of(Uri.parse(\"https://example.com/photo.jpg\"), Uri.fromFile(dest)).start(this);","handlingStrategy":"validation","validationCode":"if (destUri == null) {\n    destUri = Uri.fromFile(new File(context.getCacheDir(), \"ucrop_download_\" + System.currentTimeMillis() + \".jpg\"));\n}","typeGuard":"boolean canDownloadTo(Uri source, Uri dest) {\n    return source != null && dest != null\n        && (\"http\".equals(source.getScheme()) || \"https\".equals(source.getScheme()));\n}","tryCatchPattern":"try {\n    UCrop.of(remoteUri, destUri).start(activity);\n} catch (NullPointerException e) {\n    Log.e(TAG, \"Missing output Uri for download\", e);\n}","preventionTips":["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."],"tags":["android","ucrop","download","null-pointer","uri"],"backgroundTag":"null-argument","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}