{"record":{"id":"59a89f00b576fcfe","repo":"koral--/android-gif-drawable","slug":"giferror-open-failed-errorcode","errorCode":"GifError.OPEN_FAILED.errorCode","errorMessage":"<e.getMessage()>","messagePattern":"<e\\.getMessage\\(\\)>","errorType":"exception","errorClass":"GifIOException","httpStatus":null,"severity":"error","filePath":"android-gif-drawable/src/main/java/pl/droidsonroids/gif/GifInfoHandle.java","lineNumber":78,"sourceCode":"\tGifInfoHandle(AssetFileDescriptor afd) throws IOException {\n\t\ttry {\n\t\t\tgifInfoPtr = openFileDescriptor(afd.getFileDescriptor(), afd.getStartOffset(), false);\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tafd.close();\n\t\t\t} catch (IOException ignored) {\n\t\t\t\t//no-op\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static long openFileDescriptor(FileDescriptor fileDescriptor, long offset, boolean closeOriginalDescriptor) throws GifIOException {\n\t\tfinal int nativeFileDescriptor;\n\t\tif (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) {\n\t\t\ttry {\n\t\t\t\tnativeFileDescriptor = getNativeFileDescriptor(fileDescriptor, closeOriginalDescriptor);\n\t\t\t} catch (Exception e) { //cannot catch ErrnoException due to VerifyError on API <= 19\n\t\t\t\tthrow new GifIOException(GifError.OPEN_FAILED.errorCode, e.getMessage());\n\t\t\t}\n\t\t} else {\n\t\t\tnativeFileDescriptor = extractNativeFileDescriptor(fileDescriptor, closeOriginalDescriptor);\n\t\t}\n\t\treturn openNativeFileDescriptor(nativeFileDescriptor, offset);\n\t}\n\n\tprivate static int getNativeFileDescriptor(FileDescriptor fileDescriptor, boolean closeOriginalDescriptor) throws GifIOException, ErrnoException {\n\t\ttry {\n\t\t\tfinal int nativeFileDescriptor = createTempNativeFileDescriptor();\n\t\t\tOs.dup2(fileDescriptor, nativeFileDescriptor);\n\t\t\treturn nativeFileDescriptor;\n\t\t} finally {\n\t\t\tif (closeOriginalDescriptor) {\n\t\t\t\tOs.close(fileDescriptor);\n\t\t\t}\n\t\t}\n\t}","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/koral--/android-gif-drawable/blob/26ff795f78b7fe8bbaf375a947b2bda95fc58e3d/android-gif-drawable/src/main/java/pl/droidsonroids/gif/GifInfoHandle.java#L60-L96","documentation":"openFileDescriptor wraps any exception raised while obtaining the native file descriptor into a GifIOException with GifError.OPEN_FAILED.errorCode and the underlying exception's message. It catches generic Exception because catching ErrnoException directly causes VerifyError on API <= 19. The thrown GifIOException therefore signals the OS-level open of the descriptor failed.","triggerScenarios":"Passing an invalid/closed FileDescriptor, or a descriptor whose dup/extract fails (e.g. ErrnoException EBADF) via ParcelFileDescriptor on Android > O_MR1 to a GifDrawable built from a FileDescriptor source.","commonSituations":"Using a ParcelFileDescriptor after closing it; file permissions revoked; passing descriptors obtained from a ContentProvider that has since been released.","solutions":["Inspect e.getMessage()/cause in the GifIOException and ensure the FileDescriptor is valid and open before constructing the drawable.","Keep the ParcelFileDescriptor open while the GIF is in use; do not close it prematurely.","Check file permissions and that the underlying file still exists.","On older APIs verify the fallback extractNativeFileDescriptor path is being reached correctly."],"exampleFix":"// before\npfd.close();\nGifDrawable d = new GifDrawableBuilder().from(pfd.getFileDescriptor()).build();\n// after\nGifDrawable d = new GifDrawableBuilder().from(pfd.getFileDescriptor()).build();\n// close pfd only after the drawable is no longer needed","handlingStrategy":"try-catch","validationCode":"if (fileDescriptor != null && fileDescriptor.valid()) { /* proceed */ }","typeGuard":null,"tryCatchPattern":"try { d = new GifDrawableBuilder().from(fd).build(); } catch (GifIOException e) { if (e.getErrorCode() == GifError.OPEN_FAILED.errorCode) { /* fd open failed: re-open source or notify user */ } }","preventionTips":["Keep ParcelFileDescriptors open while the drawable lives","Validate descriptors before use","Check file permissions on the underlying resource"],"tags":["android","file-descriptor","io"],"backgroundTag":"file-open-failed","analyzedSha":"26ff795f78b7fe8bbaf375a947b2bda95fc58e3d","analyzedAt":"2026-09-10T14:37:11.595Z","contentChangedAt":"2026-09-10T14:37:11.595Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}