{"record":{"id":"3e4b4d54b33c700b","repo":"Yalantis/uCrop","slug":"outputstream-for-given-output-uri-is-null","errorCode":null,"errorMessage":"OutputStream for given output Uri is null","messagePattern":"OutputStream for given output Uri is null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java","lineNumber":237,"sourceCode":"            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);\n            } else {\n                outputStream = new FileOutputStream(new File(outputUri.getPath()));\n            }\n\n            if (outputStream != null) {\n                sink = Okio.sink(outputStream);\n                source.readAll(sink);\n            } else {\n                throw new NullPointerException(\"OutputStream for given output Uri is null\");\n            }\n        } finally {\n            BitmapLoadUtils.close(source);\n            BitmapLoadUtils.close(sink);\n            if (response != null) {\n                BitmapLoadUtils.close(response.body());\n            }\n            client.dispatcher().cancelAll();\n\n            // swap uris, because input image was downloaded to the output destination\n            // (cropped image will override it later)\n            mInputUri = mOutputUri;\n        }\n    }\n\n    @Override\n    protected void onPostExecute(@NonNull BitmapWorkerResult result) {\n        if (result.mBitmapWorkerException == null) {","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java#L219-L255","documentation":"In BitmapLoadTask.downloadFile, after a successful HTTP response, the output stream obtained for the destination Uri was null, so nothing could be written; the task throws this NullPointerException. This means the content resolver (for content:// output) or file stream creation produced no writable stream.","triggerScenarios":"Download destination Uri is a content:// Uri whose provider returns null from openOutputStream (e.g. wrong MIME/mode, read-only provider), or a file Uri whose path cannot be opened — surfaced as a null stream right before Okio.sink().","commonSituations":"Writing crops into a MediaStore/DocumentsProvider URI opened without \"w\" mode support; destination in read-only external storage; FileProvider URI that only grants read permission.","solutions":["Ensure the output content Uri is writable: use ContentResolver.openOutputStream(uri, \"w\") semantics via a provider that supports writing.","Write to an app-owned file instead (getExternalFilesDir/getCacheDir) and pass Uri.fromFile.","For MediaStore, insert a proper entry with the correct MIME type before using its Uri as output.","Grant FLAG_GRANT_WRITE_URI_PERMISSION when handing a provider Uri to uCrop."],"exampleFix":"// before\nUri out = Uri.parse(\"content://com.example.fileprovider/readonly/out.jpg\");\nUCrop.of(sourceUri, out).start(this);\n// after\nUri out = Uri.fromFile(new File(getExternalFilesDir(null), \"cropped.jpg\"));\nUCrop.of(sourceUri, out).start(this);","handlingStrategy":"try-catch","validationCode":"boolean isWritable(Uri uri) {\n    if (uri == null) return false;\n    if (\"file\".equals(uri.getScheme())) {\n        java.io.File f = new java.io.File(uri.getPath());\n        return f.getParentFile() != null && f.getParentFile().canWrite();\n    }\n    try (OutputStream os = getContentResolver().openOutputStream(uri)) {\n        return os != null;\n    } catch (Exception e) { return false; }\n}","typeGuard":"boolean isWritableDestination(android.net.Uri uri) {\n    return uri != null && (\"file\".equals(uri.getScheme()) || isWritable(uri));\n}","tryCatchPattern":"try {\n    UCrop.of(remoteUri, outputUri).start(activity);\n} catch (Exception e) {\n    Log.e(TAG, \"Cannot write crop output to \" + outputUri, e);\n}","preventionTips":["Default outputs to app-owned files (cache/external files dir) which are always writable.","For MediaStore/FileProvider destinations, verify openOutputStream(uri, \"w\") returns a stream.","Never target read-only storage; request WRITE permissions or use scoped-storage app dirs.","Grant FLAG_GRANT_WRITE_URI_PERMISSION when passing provider URIs across apps."],"tags":["android","ucrop","output-stream","null-pointer","download"],"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"}