{"record":{"id":"46c2ce17a5095ded","repo":"nostra13/Android-Universal-Image-Loader","slug":"uil-doesn-t-support-scheme-protocol-by-default","errorCode":null,"errorMessage":"UIL doesn't support scheme(protocol) by default [%s]. You should implement this support yourself (BaseImageDownloader.getStreamFromOtherSource(...))","messagePattern":"UIL doesn't support scheme\\(protocol\\) by default \\[(.+?)\\]\\. You should implement this support yourself \\(BaseImageDownloader\\.getStreamFromOtherSource\\(\\.\\.\\.\\)\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/nostra13/universalimageloader/core/download/BaseImageDownloader.java","lineNumber":280,"sourceCode":"\t\tint drawableId = Integer.parseInt(drawableIdString);\n\t\treturn context.getResources().openRawResource(drawableId);\n\t}\n\n\t/**\n\t * Retrieves {@link InputStream} of image by URI from other source with unsupported scheme. Should be overriden by\n\t * successors to implement image downloading from special sources.<br />\n\t * This method is called only if image URI has unsupported scheme. Throws {@link UnsupportedOperationException} by\n\t * default.\n\t *\n\t * @param imageUri Image URI\n\t * @param extra    Auxiliary object which was passed to {@link DisplayImageOptions.Builder#extraForDownloader(Object)\n\t *                 DisplayImageOptions.extraForDownloader(Object)}; can be null\n\t * @return {@link InputStream} of image\n\t * @throws IOException                   if some I/O error occurs\n\t * @throws UnsupportedOperationException if image URI has unsupported scheme(protocol)\n\t */\n\tprotected InputStream getStreamFromOtherSource(String imageUri, Object extra) throws IOException {\n\t\tthrow new UnsupportedOperationException(String.format(ERROR_UNSUPPORTED_SCHEME, imageUri));\n\t}\n\n\tprivate boolean isVideoContentUri(Uri uri) {\n\t\tString mimeType = context.getContentResolver().getType(uri);\n\t\treturn mimeType != null && mimeType.startsWith(\"video/\");\n\t}\n\n\tprivate boolean isVideoFileUri(String uri) {\n\t\tString extension = MimeTypeMap.getFileExtensionFromUrl(Uri.encode(uri));\n\t\tString mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);\n\t\treturn mimeType != null && mimeType.startsWith(\"video/\");\n\t}\n}\n","sourceCodeStart":262,"sourceCodeEnd":294,"githubUrl":"https://github.com/nostra13/Android-Universal-Image-Loader/blob/ba33ec64d0daaa881d35852460e78c58d086bc18/library/src/main/java/com/nostra13/universalimageloader/core/download/BaseImageDownloader.java#L262-L294","documentation":"BaseImageDownloader.getStreamFromOtherSource() throws UnsupportedOperationException (formatted with the offending URI) when an image URI's scheme is not one UIL handles natively (http, https, file, content, asset, drawable). The message explicitly tells you to implement support yourself by overriding getStreamFromOtherSource in a custom downloader. It is the library's designed extension point for custom schemes.","triggerScenarios":"Calling displayImage/loadImage with URIs like \"ftp://...\", \"data:image/...\", \"myapp://images/1\", or any scheme outside UIL's Scheme enum. Registering such URIs without installing a custom ImageDownloader that overrides getStreamFromOtherSource(String, Object).","commonSituations":"Base64 inline images (data: URIs); custom app-internal uri schemes used as cache keys; FTP or WebDAV asset servers; porting code from Picasso/Glide where data: URIs worked out of the box.","solutions":["Pass a supported scheme (http/https/file/content/asset/drawable) if the source can be expressed that way","Subclass BaseImageDownloader, override getStreamFromOtherSource to open your custom source, and register it via ImageLoaderConfiguration.downloader(...)","For data: URIs, decode the Base64 payload and return a ByteArrayInputStream from your override","Check Scheme.ofUri(uri) before calling displayImage to validate user-supplied URIs"],"exampleFix":"// before\nimageLoader.displayImage(\"myapp://avatars/42\", imageView); // throws UnsupportedOperationException\n\n// after\nclass MyAppDownloader extends BaseImageDownloader {\n    MyAppDownloader(Context ctx) { super(ctx); }\n\n    @Override\n    protected InputStream getStreamFromOtherSource(String imageUri, Object extra) throws IOException {\n        if (imageUri.startsWith(\"myapp://\")) {\n            return context.openFileInput(imageUri.substring(\"myapp://\".length()));\n        }\n        return super.getStreamFromOtherSource(imageUri, extra);\n    }\n}\n// then: new ImageLoaderConfiguration.Builder(ctx).downloader(new MyAppDownloader(ctx)).build()","handlingStrategy":"validation","validationCode":"com.nostra13.universalimageloader.core.download.ImageDownloader.Scheme scheme =\n        com.nostra13.universalimageloader.core.download.ImageDownloader.Scheme.ofUri(uri);\nboolean supported = scheme == Scheme.HTTP || scheme == Scheme.HTTPS || scheme == Scheme.FILE\n        || scheme == Scheme.CONTENT || scheme == Scheme.ASSETS || scheme == Scheme.DRAWABLE;\nif (!supported && customDownloader == null) {\n    // reject or rewrite the URI before calling displayImage\n}","typeGuard":"private static boolean isUriSupportedByDefault(String uri) {\n    try {\n        ImageDownloader.Scheme s = ImageDownloader.Scheme.ofUri(uri);\n        return s != ImageDownloader.Scheme.UNKNOWN;\n    } catch (Throwable t) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    imageLoader.displayImage(uri, imageView, options);\n} catch (UnsupportedOperationException e) {\n    // message contains the URI; fall back to a default asset\n    imageView.setImageResource(R.drawable.placeholder);\n}","preventionTips":["Whitelist URI schemes at the edge of your app (model layer / API client)","Register one custom BaseImageDownloader subclass per app covering all internal schemes","Convert data: URIs to decoded bitmaps or local files instead of feeding them to UIL"],"tags":["universal-image-loader","uri-scheme","downloader","extension-point"],"backgroundTag":null,"analyzedSha":"ba33ec64d0daaa881d35852460e78c58d086bc18","analyzedAt":"2026-08-14T15:41:15.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}