{"record":{"id":"ac82f391a177c192","repo":"pockethub/PocketHub","slug":"cannot-load-svg-from-stream","errorCode":null,"errorMessage":"Cannot load SVG from stream","messagePattern":"Cannot load SVG from stream","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/github/pockethub/android/markwon/SvgDecoder.java","lineNumber":36,"sourceCode":"        // TODO: Can we tell?\n        return true;\n    }\n\n    public Resource<SVG> decode(\n            @NonNull InputStream source, int width, int height, @NonNull Options options)\n            throws IOException {\n        try {\n            SVG svg = SVG.getFromInputStream(source);\n            if (width > 0) {\n                svg.setDocumentWidth(width);\n            }\n\n            if (height > 0) {\n                svg.setDocumentHeight(height);\n            }\n            return new SimpleResource<>(svg);\n        } catch (SVGParseException ex) {\n            throw new IOException(\"Cannot load SVG from stream\", ex);\n        }\n    }\n}","sourceCodeStart":18,"sourceCodeEnd":39,"githubUrl":"https://github.com/pockethub/PocketHub/blob/8228cb8f7197a7c2227e67ee48a2c8dc843fb553/app/src/main/java/com/github/pockethub/android/markwon/SvgDecoder.java#L18-L39","documentation":"SvgDecoder.decode() parses an image stream with com.caverock.androidsvg. When AndroidSVG cannot parse the bytes as valid SVG it throws SVGParseException, which decode() rethrows as an IOException with this message. Glide then fails the load for that resource.","triggerScenarios":"An <img> in Markdown points at a URL whose body is not a valid SVG (HTML error page, PNG served with .svg extension, truncated download, or malformed XML).","commonSituations":"Server returns HTML 404 page with 200 status or wrong Content-Type; SVG uses unsupported features/external references; compressed .svgz served as .svg; network proxy strips content.","solutions":["Confirm the URL actually serves valid SVG (check Content-Type: image/svg+xml and open the body).","Fall back to a placeholder drawable when the SVG decode fails.","Pre-validate or sanitize the SVG (e.g. via svg4everybody-style scrubbing) before decoding.","Upgrade the androidsvg dependency if the SVG uses newer/unsupported features."],"exampleFix":"// before\nGlide.with(context).load(source).into(imageView);\n// after\nGlide.with(context)\n    .load(source)\n    .placeholder(R.drawable.image_loading_icon)\n    .error(R.drawable.image_loading_icon)\n    .into(imageView);","handlingStrategy":"fallback","validationCode":"// pre-check Content-Type before decoding:\n// contentType?.contains(\"svg\") == true","typeGuard":"fun isSvg(contentType: String?, body: ByteArray): Boolean =\n    contentType?.contains(\"svg\") == true || body.size > 4 && String(body, 0, 4) == \"<svg\"","tryCatchPattern":"try {\n    val res = svgDecoder.decode(...)\n} catch (e: IOException) {\n    showPlaceholder()\n}","preventionTips":["Glide .error(placeholder) so failed SVGs degrade gracefully","Verify image URLs serve image/svg+xml","Beware .svgz / HTML-error-page responses","Keep androidsvg library updated"],"tags":["svg","image-decoding","glide","io"],"backgroundTag":"file-read-failed","analyzedSha":"8228cb8f7197a7c2227e67ee48a2c8dc843fb553","analyzedAt":"2026-09-11T10:16:17.606Z","contentChangedAt":"2026-09-11T10:16:17.606Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}