{"record":{"id":"41369440e7d03403","repo":"microg/GmsCore","slug":"failed-to-read-license-or-metadata","errorCode":null,"errorMessage":"Failed to read license or metadata","messagePattern":"Failed to read license or metadata","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"play-services-oss-licenses/src/main/java/org/microg/gms/oss/licenses/LicenseUtil.java","lineNumber":96,"sourceCode":"                }\n            } catch (IOException e) {\n                throw new RuntimeException(\"Failed to read license\", e);\n            }\n        }\n    }\n\n    private static String readStringAndClose(InputStream is, int bytesToRead) {\n        ByteArrayOutputStream bos = new ByteArrayOutputStream();\n        try {\n            byte[] bytes = new byte[1024];\n            int read;\n            while (bytesToRead > 0 && (read = is.read(bytes, 0, Math.min(bytes.length, bytesToRead))) != -1) {\n                bos.write(bytes, 0, read);\n                bytesToRead -= read;\n            }\n            is.close();\n        } catch (IOException e) {\n            throw new RuntimeException(\"Failed to read license or metadata\", e);\n        }\n        try {\n            return bos.toString(\"UTF-8\");\n        } catch (UnsupportedEncodingException e) {\n            throw new RuntimeException(\"Unsupported encoding UTF8. This should always be supported.\", e);\n        }\n    }\n}\n","sourceCodeStart":78,"sourceCodeEnd":105,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-oss-licenses/src/main/java/org/microg/gms/oss/licenses/LicenseUtil.java#L78-L105","documentation":"readStringAndClose wraps any IOException thrown while reading up to bytesToRead from the stream into a RuntimeException with this message. Callers are metadata reading (getLicensesFromMetadata) and getLicenseText, so a failure opening or reading third_party_license_metadata or third_party_licenses surfaces here.","triggerScenarios":"getLicensesFromMetadata or getLicenseText called when the underlying raw resource cannot be read: Resources.openRawResource returned a stream that fails on read (I/O error), stream already closed, or storage error mid-read.","commonSituations":"resources.getIdentifier returning an invalid/foreign-package resource so the stream is broken; corrupted resources.arsc; low-level I/O failure on device storage; reading a stream consumed elsewhere.","solutions":["Check with LicenseUtil.hasLicenses(context) before reading, and ensure res/raw/third_party_license_metadata and third_party_licenses exist in the app package (not another package/packageId)","Verify getIdentifier uses the correct package name — reading resources of a different package yields unusable streams","Catch the RuntimeException with cause IOException and degrade gracefully (show empty license list) or retry after app data repair","Rebuild/reinstall the app if resources are corrupted"],"exampleFix":"// before\nString metadata = readStringAndClose(resources.openRawResource(id), Integer.MAX_VALUE);\n// after\nif (!LicenseUtil.hasLicenses(context)) return Collections.emptyList();\ntry {\n    List<License> l = LicenseUtil.getLicensesFromMetadata(context);\n} catch (RuntimeException e) {\n    Log.w(\"Licenses\", \"Failed to read license metadata\", e);\n}","handlingStrategy":"try-catch","validationCode":"if (!LicenseUtil.hasLicenses(context)) {\n    return Collections.emptyList(); // skip metadata read entirely\n}","typeGuard":null,"tryCatchPattern":"try {\n    List<License> licenses = LicenseUtil.getLicensesFromMetadata(context);\n} catch (RuntimeException e) {\n    Log.w(\"Licenses\", \"License metadata unreadable\", e);\n    licenses = Collections.emptyList();\n}","preventionTips":["Call hasLicenses(context) first to confirm both raw resources exist and are non-empty","Ensure the raw resources are in your app's own package so getIdentifier resolves them","Catch RuntimeException around all LicenseUtil reads and render a graceful empty state"],"tags":["android","io","resources","licensing"],"backgroundTag":"file-read-failed","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}