[GH-ISSUE #1557] Extremely slow app behavior when accessing from internal LAN through reverse proxy #974

Closed
opened 2026-03-02 11:54:05 +03:00 by kerem · 8 comments
Owner

Originally created by @atrugiel69 on GitHub (Jun 7, 2025).
Original GitHub issue: https://github.com/karakeep-app/karakeep/issues/1557

Describe the Bug

I am using Karakeep on a Linux Mint machine.
I reverse proxy using nginx and DuckDNS to access from outside my network on https://mysubdomain.duckdns.org

Configuration for nginx is this:

server {
listen 443 ssl;
listen [::]:443 ssl;
server_name mysubdomain.duckdns.org;

ssl_certificate /etc/letsencrypt/live/mysubdomain.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysubdomain.duckdns.org/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

# Karakeep served from the root
location / {
    proxy_pass http://localhost:3000/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

}

server {
listen 80;
listen [::]:80;
server_name mysubdomain.duckdns.org;
return 301 https://$host$request_uri;
}

I added the Duck DNS subdomain to my exceptions for DNS Rebind Protection on my Fritzbox router and everything works just fine when accessing from outside the LAN.

When inside the LAN, accessing from a browser (Firefox in my case) from my smartphone works perfectly. But if I use https://mysubdomain.duckdns.org as address in the Android app, everything is incredibly slow. Initial login seems to fail, so I press the debug button, it starts testing the connection and after a couple of minutes it says everything is ok. If I go back from debug I access my list of bookmarks but they are shown without the small pictures (something that never happens when accessing from a browser). If I use the share function to hoard a new link from Android, the app displays the "Hoarding" message for, again, a couple of minutes before giving confirmation that the link has been saved.

If there's any extra information I could provide, just ask. I have tried to explain to the best of my capabilities...

Steps to Reproduce

Above I tried to describe my workflow thoroughly. It's quite specific probably. So, I don't know if this could be easy to reproduce. I post this mainly hoping there's some extra steps to debug this and understand what's happening. Nginx logs don't show errors.

Expected Behaviour

Expected behavior would be for the app to be as responsive as it is from outside the LAN from inside the LAN.
Note that if I configure the local IP address in the app, it's normally responsive but, clearly, this way I can't access karakeep from outside my network.

Screenshots or Additional Context

No response

Device Details

Samsung Galaxy S23+, Android 15, Android Karakeep App 1.6.9

Exact Karakeep Version

Karakeep v 0.24.1

Have you checked the troubleshooting guide?

  • I have checked the troubleshooting guide and I haven't found a solution to my problem
Originally created by @atrugiel69 on GitHub (Jun 7, 2025). Original GitHub issue: https://github.com/karakeep-app/karakeep/issues/1557 ### Describe the Bug I am using Karakeep on a Linux Mint machine. I reverse proxy using nginx and DuckDNS to access from outside my network on https://mysubdomain.duckdns.org Configuration for nginx is this: server { listen 443 ssl; listen [::]:443 ssl; server_name mysubdomain.duckdns.org; ssl_certificate /etc/letsencrypt/live/mysubdomain.duckdns.org/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mysubdomain.duckdns.org/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Karakeep served from the root location / { proxy_pass http://localhost:3000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } server { listen 80; listen [::]:80; server_name mysubdomain.duckdns.org; return 301 https://$host$request_uri; } I added the Duck DNS subdomain to my exceptions for DNS Rebind Protection on my Fritzbox router and everything works just fine when accessing from outside the LAN. When inside the LAN, accessing from a browser (Firefox in my case) from my smartphone works perfectly. But if I use https://mysubdomain.duckdns.org as address in the Android app, everything is incredibly slow. Initial login seems to fail, so I press the debug button, it starts testing the connection and after a couple of minutes it says everything is ok. If I go back from debug I access my list of bookmarks but they are shown without the small pictures (something that never happens when accessing from a browser). If I use the share function to hoard a new link from Android, the app displays the "Hoarding" message for, again, a couple of minutes before giving confirmation that the link has been saved. If there's any extra information I could provide, just ask. I have tried to explain to the best of my capabilities... ### Steps to Reproduce Above I tried to describe my workflow thoroughly. It's quite specific probably. So, I don't know if this could be easy to reproduce. I post this mainly hoping there's some extra steps to debug this and understand what's happening. Nginx logs don't show errors. ### Expected Behaviour Expected behavior would be for the app to be as responsive as it is from outside the LAN from inside the LAN. Note that if I configure the local IP address in the app, it's normally responsive but, clearly, this way I can't access karakeep from outside my network. ### Screenshots or Additional Context _No response_ ### Device Details Samsung Galaxy S23+, Android 15, Android Karakeep App 1.6.9 ### Exact Karakeep Version Karakeep v 0.24.1 ### Have you checked the troubleshooting guide? - [x] I have checked the troubleshooting guide and I haven't found a solution to my problem
kerem 2026-03-02 11:54:05 +03:00
Author
Owner

@atrugiel69 commented on GitHub (Jun 7, 2025):

As an extra datapoint, the app, just once, gave me an error trying to connect, stating

Network connection failed: Failed to connect to mysubdomain.duckdns.org/MyServerOutsideNumericIPaddress:443

Never saw that error again, even after repeated purging of data and cache for the app (I even uninstalled it and reinstalled it once).

<!-- gh-comment-id:2952977969 --> @atrugiel69 commented on GitHub (Jun 7, 2025): As an extra datapoint, the app, just once, gave me an error trying to connect, stating Network connection failed: Failed to connect to mysubdomain.duckdns.org/MyServerOutsideNumericIPaddress:443 Never saw that error again, even after repeated purging of data and cache for the app (I even uninstalled it and reinstalled it once).
Author
Owner

@ebenoist commented on GitHub (Jun 7, 2025):

@atrugiel69 I use a similar setup, but use tailscale and digital ocean for DNS with traefik as a reverse proxy. My installation on a intel nuc is pretty snappy. Different OS platforms will have their own resolution stack which could be the issue here or something with duckdns, but I'm not familiar with that service.

<!-- gh-comment-id:2953190798 --> @ebenoist commented on GitHub (Jun 7, 2025): @atrugiel69 I use a similar setup, but use tailscale and digital ocean for DNS with traefik as a reverse proxy. My installation on a intel nuc is pretty snappy. Different OS platforms will have their own resolution stack which could be the issue here or something with duckdns, but I'm not familiar with that service.
Author
Owner

@atrugiel69 commented on GitHub (Jun 8, 2025):

@atrugiel69 I use a similar setup, but use tailscale and digital ocean for DNS with traefik as a reverse proxy. My installation on a intel nuc is pretty snappy. Different OS platforms will have their own resolution stack which could be the issue here or something with duckdns, but I'm not familiar with that service.

This is absolutely not a matter of performance. The same machine, the same network, if I connect on the app using the local IP address the app absolutely flies. I have a NUC i7 with 32GB of RAM.

If I use the mysubdomain.duckdns.org address from inside the LAN, the same karakeep instance absolutely flies when accessed from Firefox (I even tested with a chromium based browser, Kiwi Browser, same result).

It slows to a crawl, or worse, when I try to use the app with mysubdomain.duckdns.org. Same app, same network, if I use the internal IP to connect, it flies once more. Same app, outside the LAN, if I use mysubdomain.duckdns.org it flies too.

The app must be doing something different from a normal web browser when accessing the server. Point is... what?

<!-- gh-comment-id:2953870929 --> @atrugiel69 commented on GitHub (Jun 8, 2025): > [@atrugiel69](https://github.com/atrugiel69) I use a similar setup, but use tailscale and digital ocean for DNS with traefik as a reverse proxy. My installation on a intel nuc is pretty snappy. Different OS platforms will have their own resolution stack which could be the issue here or something with duckdns, but I'm not familiar with that service. This is absolutely not a matter of performance. The same machine, the same network, if I connect on the app using the local IP address the app absolutely flies. I have a NUC i7 with 32GB of RAM. If I use the mysubdomain.duckdns.org address from inside the LAN, the same karakeep instance absolutely flies when accessed from Firefox (I even tested with a chromium based browser, Kiwi Browser, same result). It slows to a crawl, or worse, when I try to use the app with mysubdomain.duckdns.org. Same app, same network, if I use the internal IP to connect, it flies once more. Same app, outside the LAN, if I use mysubdomain.duckdns.org it flies too. The app must be doing something different from a normal web browser when accessing the server. Point is... what?
Author
Owner

@atrugiel69 commented on GitHub (Jun 8, 2025):

Extra data point. The iOS app, on an iPad Pro 12.9" 2nd Generation, works just fine when accessing Karakeep from inside my LAN, using mysubdomain.duckdns.org.

At this point I suspect there's a problem with however the Android app handles the connection...

<!-- gh-comment-id:2953899399 --> @atrugiel69 commented on GitHub (Jun 8, 2025): Extra data point. The iOS app, on an iPad Pro 12.9" 2nd Generation, works just fine when accessing Karakeep from inside my LAN, using mysubdomain.duckdns.org. At this point I suspect there's a problem with however the Android app handles the connection...
Author
Owner

@atrugiel69 commented on GitHub (Jun 8, 2025):

Ended up "solving" this by configuring dnsmasq for my local server and setting that machine as DNS server for my Android smartphone.
I think, unless there's a bug to be found somewhere to justify what I experienced, that a nice feature to add to the app would be a different server address to configure for local connection (tied to WiFi name, for instance). This is something that many Subsonic (and derivatives) apps offer. And it simplify lives for people that do not want to spend a whole afternoon devising a custom solution like I did.

<!-- gh-comment-id:2954293179 --> @atrugiel69 commented on GitHub (Jun 8, 2025): Ended up "solving" this by configuring dnsmasq for my local server and setting that machine as DNS server for my Android smartphone. I think, unless there's a bug to be found somewhere to justify what I experienced, that a nice feature to add to the app would be a different server address to configure for local connection (tied to WiFi name, for instance). This is something that many Subsonic (and derivatives) apps offer. And it simplify lives for people that do not want to spend a whole afternoon devising a custom solution like I did.
Author
Owner

@atrugiel69 commented on GitHub (Jun 9, 2025):

I have asked a LLM AI I have used to work around this to write a small report on what it found out.

DNS Resolution Behavior Report for Karakeep App (Android vs. iOS)

Background

Our local network uses dnsmasq for DNS resolution with upstream servers defined for both IPv4 and IPv6. The domain in question is mysubdomain.duckdns.org, which is used by the Karakeep app. We initially defined only an IPv4 override for this domain. Over time, we observed that when the Karakeep app attempted to resolve AAAA (IPv6) records for this domain, the app behaved sluggishly or failed to fetch content (for example, graphical previews), ultimately failing to log in the user after a log out.

Original Configuration

Initially, we had a dnsmasq configuration, using Quad9 DNS as main DNS, of the form:

server=9.9.9.9
server=149.112.112.112
address=/mysubdomain.duckdns.org/192.168.1.55
filter-AAAA

Here, the global filter-AAAA directive was used to force dnsmasq to return only IPv4 (A) records even when AAAA records were available upstream. Although this ensured that clients would use IPv4, it applied to all domains and could potentially hinder environments where IPv6 connectivity is beneficial. The Karakeep app was always working correctly, but several other apps basically stopped working, depending evidently on fetching web content while accessing IPv6

Issue Observed Without Filtering

When removing filter-AAAA to allow IPv6 (i.e., enabling dual‑stack responses), our observations were:

  • Android Behavior:
    The Karakeep app on Android would log in when using mobile data (where IPv6 resolution might differ) but exhibit significant slowdown or failure to display content (e.g., graphical previews) when connected via WiFi. It appears that the Android networking stack was attempting to use IPv6 first, which led to delays when valid IPv6 connectivity for mysubdomain.duckdns.org was not present.

  • iOS Behavior:
    The iOS version of the app did not exhibit the same slowness or failure despite similar DNS conditions, suggesting a difference in how the platform handles dual‑stack DNS resolution (or fallback from IPv6 to IPv4).

Experimented Workaround

To address this, we modified our dnsmasq configuration to explicitly “override” the AAAA response for mysubdomain.duckdns.org while still allowing IPv6 upstream servers for other queries. The resulting configuration is as follows:

server=9.9.9.9
server=149.112.112.112
server=2620:fe::fe
server=2620:fe::9
# Global filter-AAAA disabled
address=/mysubdomain.duckdns.org/192.168.1.55
address=/mysubdomain.duckdns.org/::   # Override AAAA queries with a “null” IPv6 answer

Explanation:

  • The first address line ensures that any A query for mysubdomain.duckdns.org returns the local IPv4 address.
  • The second address line (using ::) acts as a hack to yield an empty or “null” AAAA record. This effectively tells clients that no IPv6 address should be used for the domain, avoiding delays due to failed IPv6 connections on Android.

Observations After the Change

  • Android Performance:
    With the above configuration in place, the Karakeep app on Android resumed fast performance—graphical previews and content updates responded immediately, even on LAN WiFi. Logging out and logging back in was instant.

  • Implication:
    This indicates that the original issues were likely due to the Android networking stack’s handling of dual-stack DNS responses. Without a proper AAAA record (or with an invalid one), Android would time out or delay fallback to IPv4. By forcing a “null” AAAA result for mysubdomain.duckdns.org, we ensure the Android device uses the IPv4 route immediately.

Considerations and Recommendations

  • Per-Domain vs. Global Behavior:
    Since dnsmasq does not natively support per‑domain filtering of AAAA responses, this workaround using dual address directives is currently the simplest way to force IPv4 for mysubdomain.duckdns.org while preserving dual‑stack functionality for all other domains.

  • Platform-Specific Behavior:
    The discrepancy between Android and iOS behavior suggests that modifications to how DNS resolution is handled in the app (or a configuration option allowing the app to prefer IPv4) could be beneficial. It may be worthwhile to investigate if the Android app can be improved to either ignore AAAA responses for this domain, or attempt a faster fallback mechanism to IPv4.

Conclusion

The necessity of filtering or overriding AAAA responses for mysubdomain.duckdns.org indicates that the Karakeep Android app is sensitive to IPv6 DNS resolution—even though the iOS app is not. Our current solution forces IPv4 usage for that domain, avoiding delays and performance issues on Android. This discrepancy might warrant further adjustments in either the app’s DNS handling logic or a more granular DNS server configuration in future updates.


<!-- gh-comment-id:2955416943 --> @atrugiel69 commented on GitHub (Jun 9, 2025): I have asked a LLM AI I have used to work around this to write a small report on what it found out. # DNS Resolution Behavior Report for Karakeep App (Android vs. iOS) ## Background Our local network uses **dnsmasq** for DNS resolution with upstream servers defined for both IPv4 and IPv6. The domain in question is `mysubdomain.duckdns.org`, which is used by the Karakeep app. We initially defined only an IPv4 override for this domain. Over time, we observed that when the Karakeep app attempted to resolve AAAA (IPv6) records for this domain, the app behaved sluggishly or failed to fetch content (for example, graphical previews), ultimately failing to log in the user after a log out. ## Original Configuration Initially, we had a dnsmasq configuration, using Quad9 DNS as main DNS, of the form: ``` server=9.9.9.9 server=149.112.112.112 address=/mysubdomain.duckdns.org/192.168.1.55 filter-AAAA ``` Here, the global `filter-AAAA` directive was used to force dnsmasq to return only IPv4 (A) records even when AAAA records were available upstream. Although this ensured that clients would use IPv4, it applied to all domains and could potentially hinder environments where IPv6 connectivity is beneficial. The Karakeep app was always working correctly, but several other apps basically stopped working, depending evidently on fetching web content while accessing IPv6 ## Issue Observed Without Filtering When removing `filter-AAAA` to allow IPv6 (i.e., enabling dual‑stack responses), our observations were: - **Android Behavior:** The Karakeep app on Android would log in when using mobile data (where IPv6 resolution might differ) but exhibit significant slowdown or failure to display content (e.g., graphical previews) when connected via WiFi. It appears that the Android networking stack was attempting to use IPv6 first, which led to delays when valid IPv6 connectivity for `mysubdomain.duckdns.org` was not present. - **iOS Behavior:** The iOS version of the app did not exhibit the same slowness or failure despite similar DNS conditions, suggesting a difference in how the platform handles dual‑stack DNS resolution (or fallback from IPv6 to IPv4). ## Experimented Workaround To address this, we modified our dnsmasq configuration to explicitly “override” the AAAA response for `mysubdomain.duckdns.org` while still allowing IPv6 upstream servers for other queries. The resulting configuration is as follows: ```conf server=9.9.9.9 server=149.112.112.112 server=2620:fe::fe server=2620:fe::9 # Global filter-AAAA disabled address=/mysubdomain.duckdns.org/192.168.1.55 address=/mysubdomain.duckdns.org/:: # Override AAAA queries with a “null” IPv6 answer ``` **Explanation:** - The first `address` line ensures that any A query for `mysubdomain.duckdns.org` returns the local IPv4 address. - The second `address` line (using `::`) acts as a hack to yield an empty or “null” AAAA record. This effectively tells clients that no IPv6 address should be used for the domain, avoiding delays due to failed IPv6 connections on Android. ## Observations After the Change - **Android Performance:** With the above configuration in place, the Karakeep app on Android resumed fast performance—graphical previews and content updates responded immediately, even on LAN WiFi. Logging out and logging back in was instant. - **Implication:** This indicates that the original issues were likely due to the Android networking stack’s handling of dual-stack DNS responses. Without a proper AAAA record (or with an invalid one), Android would time out or delay fallback to IPv4. By forcing a “null” AAAA result for `mysubdomain.duckdns.org`, we ensure the Android device uses the IPv4 route immediately. ## Considerations and Recommendations - **Per-Domain vs. Global Behavior:** Since dnsmasq does not natively support per‑domain filtering of AAAA responses, this workaround using dual `address` directives is currently the simplest way to force IPv4 for `mysubdomain.duckdns.org` while preserving dual‑stack functionality for all other domains. - **Platform-Specific Behavior:** The discrepancy between Android and iOS behavior suggests that modifications to how DNS resolution is handled in the app (or a configuration option allowing the app to prefer IPv4) could be beneficial. It may be worthwhile to investigate if the Android app can be improved to either ignore AAAA responses for this domain, or attempt a faster fallback mechanism to IPv4. ## Conclusion The necessity of filtering or overriding AAAA responses for `mysubdomain.duckdns.org` indicates that the Karakeep Android app is sensitive to IPv6 DNS resolution—even though the iOS app is not. Our current solution forces IPv4 usage for that domain, avoiding delays and performance issues on Android. This discrepancy might warrant further adjustments in either the app’s DNS handling logic or a more granular DNS server configuration in future updates. ---
Author
Owner

@MohamedBassem commented on GitHub (Jun 15, 2025):

I honestly can't see how this can be a karakeep issue, and I'm glad you worked around it, so I'll close the issue.

If you want to have support for different addresses on local networks, this can be a separate FR.

<!-- gh-comment-id:2974599361 --> @MohamedBassem commented on GitHub (Jun 15, 2025): I honestly can't see how this can be a karakeep issue, and I'm glad you worked around it, so I'll close the issue. If you want to have support for different addresses on local networks, this can be a separate FR.
Author
Owner

@atrugiel69 commented on GitHub (Jun 15, 2025):

Well, there is something strange happening with the Android version of your app that doesn't happen in the iOS version. Isn't that worth investigating? On iOS I did not need any extra workaround. Nor did I need workarounds when accessing the web version. Just from the Android app.

I have tried reporting as completely as possible but I am available for any extra info you might need.

<!-- gh-comment-id:2974658571 --> @atrugiel69 commented on GitHub (Jun 15, 2025): Well, there is something strange happening with the Android version of your app that doesn't happen in the iOS version. Isn't that worth investigating? On iOS I did not need any extra workaround. Nor did I need workarounds when accessing the web version. Just from the Android app. I have tried reporting as completely as possible but I am available for any extra info you might need.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/karakeep#974
No description provided.