DiskLruCache line 683
okhttp3.internal.cache.DiskLruCache.trimToSize
Fatal Exception: java.util.NoSuchElementException
at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:349)
at java.util.LinkedHashMap$ValueIterator.next(LinkedHashMap.java:370)
at okhttp3.internal.cache.DiskLruCache.trimToSize(SourceFile:683)
at okhttp3.internal.cache.DiskLruCache$1.run(SourceFile:176)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Is this a once off or happening regularly? Can you provide more information e.g. it looks like this is with an older version of okhttp based on line numbers.
Something in the cache is getting corrupted, so that the cache is empty but doesn’t know it. An executable test case would help to reproduce.
I have the same bug report in okhttp:3.12.0
and this bug has been reported too many times.
@swankjesse @yschimke

java.util.NoSuchElementException: empty message
java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:759)
java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:785)
okhttp3.internal.cache.DiskLruCache.trimToSize(DiskLruCache.java:684)
okhttp3.internal.cache.DiskLruCache$1.run(DiskLruCache.java:177)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
java.lang.Thread.run(Thread.java:764)
I have the same bug with okhttp:3.12.1,has it fixed in 3.12.x version?
OkHttp DiskLruCache java.util.NoSuchElementException
java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:762)
java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:788)
okhttp3.internal.cache.DiskLruCache.trimToSize(DiskLruCache.java:684)
okhttp3.internal.cache.DiskLruCache$1.run(DiskLruCache.java:177)
java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
java.lang.Thread.run(Thread.java:784)
I got more than 150 crashes everyday because of this issue
Fatal Exception: java.util.NoSuchElementException
at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:759)
at java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:785)
at okhttp3.internal.cache.DiskLruCache.trimToSize(DiskLruCache.java:652)
at okhttp3.internal.cache.DiskLruCache$cleanupTask$1.runOnce(DiskLruCache.java:180)
at okhttp3.internal.concurrent.TaskRunner.runTask(TaskRunner.java:115)
at okhttp3.internal.concurrent.TaskRunner.access$runTask(TaskRunner.java:41)
at okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Any update on this?
This bug is my top 1 crash on Crashlytics and 92% of crashes are on android 10.
My app have more than one process, all of them use okhttp. Not sure if this behavior causes the issue.
Nope. From https://github.com/square/okhttp/issues/6453 the best advice is make extra sure you never create two Cache instances pointing at the same directory. But since this is failing on java collection iteration, not file corruption, even that seems unlikely. So probably a separate issue.
@redmanit any contextual information you can provide? device types, OS versions, okhttp version? If you are not on 3.12.12 or 4.9.0 please upgrade to one of those.
Nope. From #6453 the best advice is make extra sure you never create two Cache instances pointing at the same directory. But since this is failing on java collection iteration, not file corruption, even that seems unlikely. So probably a separate issue.
@redmanit any contextual information you can provide? device types, OS versions, okhttp version? If you are not on 3.12.12 or 4.9.0 please upgrade to one of those.
As I said my app has more than one processes and all of them use Glide so there are more than one Cache instance pointing at the same directory. This is expected behavior so I can't change that.
I'm using okhttp 4.3.1 (with Retrofit), will update soon but I don't think it will fix this very old issue.
About the crashes: 93% Android 10, 4% Android 9, 3 % Android 8...; 75% Samsung, 12% HMD Global, 3% Xiaomi...
I don't think we can really support multiple processes using same cache. So if it works then stick with it, but if not then separate them out.
I don't think we can really support multiple processes using same cache. So if it works then stick with it, but if not then separate them out.
You don't need to support mutiple processes, just don't crash.
Unfortunately it's difficult to determine if there are multiple processes. For example, Firefox uses a PID file but it may refuse to launch after a crash.
Most helpful comment
I have the same bug report in okhttp:3.12.0
and this bug has been reported too many times.
@swankjesse @yschimke
java.util.NoSuchElementException: empty message
java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:759)
java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:785)
okhttp3.internal.cache.DiskLruCache.trimToSize(DiskLruCache.java:684)
okhttp3.internal.cache.DiskLruCache$1.run(DiskLruCache.java:177)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
java.lang.Thread.run(Thread.java:764)