So, this post comes after about two or three days of troubleshooting a really weird and sudden issue I started encountering on my Android phone running KitKat 4.4.4.

It all started when I was out at a bar and trying to upload a picture to Instagram using the Instagram app. The kept crashing after about 10 seconds of using it and I kept having to race against time to get this picture uploaded before the app crashed. I was eventually successful. A day passed and after looking at logcat when opening Instagram I figured out that it was only happening when a video loaded in my feed. The app was trying to write to a file at /storage/emulated/0/Android/data/com.instagram.android/cache/video/journal.tmp, which kept being denied. The stack trace looked something like this:

01-06 18:34:07.808  7420  7447 E a       : java.lang.RuntimeException: An error occured while executing doInBackground()
01-06 18:34:07.808  7420  7447 E a       :  at android.support.v4.a.l.done(ModernAsyncTask.java:137)
01-06 18:34:07.808  7420  7447 E a       :  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
01-06 18:34:07.808  7420  7447 E a       :  at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
01-06 18:34:07.808  7420  7447 E a       :  at java.util.concurrent.FutureTask.run(FutureTask.java:242)
01-06 18:34:07.808  7420  7447 E a       :  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
01-06 18:34:07.808  7420  7447 E a       :  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
01-06 18:34:07.808  7420  7447 E a       :  at java.lang.Thread.run(Thread.java:841)
01-06 18:34:07.808  7420  7447 E a       : Caused by: java.lang.IllegalArgumentException: Invalid path: /storage/emulated/0/Android/data/com.instagram.android/cache/video
01-06 18:34:07.808  7420  7447 E a       :  at android.os.StatFs.doStat(StatFs.java:46)
01-06 18:34:07.808  7420  7447 E a       :  at android.os.StatFs.(StatFs.java:39)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.common.h.a.b.a(CacheUtil.java:19)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.common.h.c.a.e(IgVideoCache.java:283)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.common.h.c.a.d(IgVideoCache.java:271)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.common.h.c.a.f(IgVideoCache.java:302)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.common.h.c.a.a(IgVideoCache.java:168)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.common.h.c.a.a(IgVideoCache.java:149)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.android.fragment.e.b(AbstractFeedFragment.java:597)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.android.fragment.e.b(AbstractFeedFragment.java:516)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.common.a.a.a.g(AbstractRequest.java:94)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.api.k.a.a.g(AbstractIgRequest.java:80)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.common.a.a.i.u(LoaderRequestPerformer.java:93)
01-06 18:34:07.808  7420  7447 E a       :  at com.instagram.common.a.a.i.d(LoaderRequestPerformer.java:61)
01-06 18:34:07.808  7420  7447 E a       :  at android.support.v4.a.a.e(AsyncTaskLoader.java:242)
01-06 18:34:07.808  7420  7447 E a       :  at android.support.v4.a.b.e(AsyncTaskLoader.java:51)
01-06 18:34:07.808  7420  7447 E a       :  at android.support.v4.a.b.b(AsyncTaskLoader.java:40)
01-06 18:34:07.808  7420  7447 E a       :  at android.support.v4.a.k.call(ModernAsyncTask.java:123)
01-06 18:34:07.808  7420  7447 E a       :  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
01-06 18:34:07.808  7420  7447 E a       :  ... 3 more
01-06 18:34:07.808  7420  7447 E a       : Caused by: libcore.io.ErrnoException: statvfs failed: ENOENT (No such file or directory)
01-06 18:34:07.808  7420  7447 E a       :  at libcore.io.Posix.statvfs(Native Method)
01-06 18:34:07.808  7420  7447 E a       :  at libcore.io.ForwardingOs.statvfs(ForwardingOs.java:132)
01-06 18:34:07.808  7420  7447 E a       :  at android.os.StatFs.doStat(StatFs.java:44)
01-06 18:34:07.808  7420  7447 E a       :  ... 21 more

I spent about an hour trying to fix this by uninstalling the app, reinstalling, rebooting into recovery and wiping the dalvik cache, reloading old versions from Titanium Backup and eventually gave up. Then last night, I started encountering the same issue with a different app. I eventually came across a fairly recent bug report filed against Android (https://code.google.com/p/android/issues/detail?id=81357) and got in touch with the developer that reported the bug as it sounded like what I was running into, but on API level 19 instead of 21 (Lollipop).

We exchanged a couple emails and I got some more information from him, including a couple workarounds. After I got out of work today, I started working on this and ended up discovering that I wasn't encountering the same issue. One of the workarounds involves adding the WRITE_EXTERNAL_STORAGE permission to the app manifest and the Instagram app already includes this permission. So now I'm back to square one and have no idea what's causing this to happen (but least I've been able to rule out a couple things so far). Being stuck and not know what to do next, I start reading more about the API behind data storage (http://www.doubleencore.com/2014/03/android-external-storage/) and after getting a clearer picture of how Android permissions really work (hint: that bastard stepchild called SELinux), I had the genius idea of tail -f'ing the /data/misc/audit/audit.log and opening Instagram. Then I saw it; avc deny errors all over the place.

Now I know what is causing this to happen, but I have no idea why. What got me pointed in the right direction was another bug report (https://code.google.com/p/android-developer-preview/issues/detail?id=899) and saw that someone had posted a restorecon command, which didn't help me because the -F flag has been dropped and is no longer supported. Eventually, I came across a post on XDA mentioning the same command, but different flags and directory path. Specifically, as root:

restorecon -Rv /data/media

Then reboot. I shit you not, that's all I had to do. Run that command as root and reboot my phone and this problem went away.

In the end, I have no idea what goofed the context permissions on this directory (which maps back to /storage/emulated) and probably will never find out, but I thought I'd type this all up in case someone else runs into this issue and can't figure out how hell to fix it without wiping the phone back to factory defaults and hoping that fixes it, but ends up finding this blog post first instead.