See Federated Wiki’s “Origin Server Acts as a Proxy”.
Note: Some of the following comments on mixed mode are (or were?) incorrect, localhost is considered a Secure Context. If the browsers blocks access, this is a browser bug. matrix ![]()
Some browser were very slow with implementing the localhost security context correctly, especially with regard to localhost subdomains.
N.B. 'HTTPS vs HTTP (mixed content)' section revised. See 4. HTTPS vs HTTP (mixed content), updated
ChatGPT 5
Here’s a compact “why this breaks on Ubuntu-with-IPv6” map plus a do-now troubleshooting plan.
# Why the localhost proxy/fork can fail on IPv6 Ubuntu Federated Wiki’s “origin server acts as a proxy” pattern means your browser often asks the page’s origin to fetch another wiki’s page on your behalf (a “proxy” hop) so the browser doesn’t directly poke private addresses like `localhost`. That indirection is key to forking across sites.
On Ubuntu with IPv6 enabled, several gotchas pop up: 1. `localhost` resolves to IPv6 first * On Ubuntu, `localhost` typically maps to **`::1`** and **`127.0.0.1`**. If any component assumes only IPv4 (e.g., whitelists `127.0.0.1`), you’ll get “can’t connect” or subtle CORS/origin mismatches. * Similarly, URLs like `http://[::1]:3000` are *different origins* than `http://127.0.0.1:3000` or `http://localhost:3000`, which can break cookie scope, SameSite checks, or ad-hoc origin checks. 2. Listener/bind mismatch * If your wiki/process or reverse proxy listens only on `127.0.0.1` (IPv4) but the client tries `::1` (IPv6), or vice-versa, connections fail. Linux dual-stack rules vary by how the app sets `IPV6_V6ONLY`. Node/Express or your front proxy (Caddy/Ngininx) may end up reachable on one family but not the other. 3. Browser private-network protections (PNA) & CORS * When a page loaded from a **public/remote** origin tries to reach a **private** origin (like `http://localhost`), modern browsers apply **Private Network Access** preflights and restrictions. If the workflow ever tries to fetch your local wiki **directly from the page** (instead of via the same-origin proxy), the browser may block it with CORS/PNA errors. (You’ll see “blocked by CORS policy: preflight to private network” style messages in DevTools.)
4. HTTPS vs HTTP (mixed content), updated * **`http://localhost` is a “potentially trustworthy origin.”** Modern browsers treat it as a secure context, so an HTTPS page is **allowed** to fetch from `http://localhost` without triggering a generic “mixed content” block. * Where you *do* get blocked is **Private Network Access (PNA)**: if the requesting page is not itself a secure context (i.e. plain `http://…`), or if the local server does not answer the preflight with `Access-Control-Allow-Private-Network: true`. That’s what your console shows. * Subdomains like `foo.localhost` have only more recently been brought into this “trustworthy” set; some browsers were slow to align. If you need consistency, prefer bare `localhost`, `127.0.0.1`, or `[::1]`. --- So: no “mixed content” issue for `http://localhost`. The real constraints are (a) whether the requesting page is HTTPS (secure context), and (b) whether your local wiki opts in to PNA.
5. Reverse proxy on your server not IPv6-ready * If you front the wiki with Caddy/Nginx and only the IPv4 `listen`/firewall is open (or `ipv6only` is mis-set), your proxy path may succeed in v4 tests but fail when a stack chooses v6 first. 6. Cookie/Origin subtlety with IPv6 literals * Cookies sent for `domain=localhost` don’t attach to the literal host `[::1]`. Conversely, a site reached as `[::1]` is a different origin from `localhost`. Any code that compares origins as strings can short-circuit federation/proxy logic. 7. Hostname routing or DNS overrides * Extra `/etc/hosts` entries, or a corporate VPN/AV that intercepts “loopback” or blocks local service discovery, can cause only-on-IPv6 failures. 8. Security mode or plugin assumptions * If your deployment’s security mode (e.g., `friends`) or proxy plugin endpoint expects only IPv4 loopback or a specific Host header, IPv6 paths may get 403/404. # Fast triage (10–15 minutes) 1. Confirm resolution & listeners ```bash getent hosts localhost ss -ltnp | grep 3000 # or your wiki port curl --ipv4 -sI http://127.0.0.1:3000/ | head curl -g --ipv6 -sI http://[::1]:3000/ | head ``` * Goal: both v4 and v6 work locally. If v4 works and v6 doesn’t (or vice-versa), fix your bind. 2. Watch the failure in the browser * Open DevTools → Network + Console while attempting the fork. * If you see **CORS/PNA** or **mixed content** errors, that means the page tried to call `localhost` **directly** (not via the same-origin proxy). That’s a browser block, not a server crash. 3. Try all three loopback forms in the UI/URL bar * `http://localhost:3000` * `http://127.0.0.1:3000` * `http://[::1]:3000` If one works and the others don’t, you have an origin/IPv6 disparity. 4. Force IPv4 as a control test * Temporarily use the IPv4 literal everywhere (`127.0.0.1`) in any local addresses you enter or configure. If this unblocks forking, your issue is squarely IPv6/localhost handling. # Fix patterns (pick what fits your setup) A) Make the local wiki reachable on both stacks * Configure the wiki (or its front proxy) to **listen on both IPv4 and IPv6**. * Nginx: `listen 127.0.0.1:3000;` and `listen [::1]:3000;` (or `listen [::]:3000; ipv6only=off;`). * Caddy: add both `localhost` and `[::1]` site addresses, or bind `:3000` and ensure IPv6 is not disabled. * Verify with the `curl --ipv4/--ipv6` checks above. B) Normalize the origin used by the browser * Wherever you type or embed your local address, **pick one canonical form** (e.g., `http://localhost:3000`) and stick to it. * Avoid mixing `[::1]`, `127.0.0.1`, and `localhost` in the same session; it fragments cookies/origins. C) Avoid direct browser calls to `localhost` from a remote page * Make sure the **“origin server proxy”** paths are used so the browser only talks to the page’s origin, not your `localhost`. (If the current flow tries to fetch local content directly, you will hit PNA/mixed-content walls.) ([fed.wiki.org][1]) * If you control the remote server, ensure its proxy endpoint will *not* attempt to fetch `http://localhost:...` on **its** loopback (which is meaningless); local resources must be provided by the client side or via an explicit upload/POST. D) CORS/headers sanity if any cross-origin remains * If there is a same-machine cross-origin hop (not ideal), your local wiki must reply with: * `Access-Control-Allow-Origin: <remote origin>` (not `*` if cookies involved) * `Access-Control-Allow-Credentials: true` if cookies needed * Handle **OPTIONS** preflight (especially for PNA). E) HTTPS consistency * If the remote origin is `https://…`, keep the whole chain HTTPS *or* ensure the proxy endpoint terminates HTTPS and the browser **never** calls `http://localhost` directly. F) Firewall/ufw ```bash sudo ufw status verbose # If you restrict, allow v6 loopback or just rely on loopback-only binds. ``` * Ensure nothing blocks ::1 traffic locally and that reverse proxies can reach the wiki backend on both families. G) Hosts file hygiene * `/etc/hosts` should include **both**: ``` 127.0.0.1 localhost ::1 localhost ``` * Remove odd aliases mapping `localhost` to external addresses. H) App-level checks (Node/Express examples) * When calling `server.listen(port)`, verify it binds to the right interface; if you pass a hostname, try `::` (dual-stack) or omit it. * If any code whitelists `127.0.0.1`, add `::1`. If it string-compares origins, normalize them (e.g., treat `localhost`, `127.0.0.1`, and `[::1]` as equivalent for “local” checks). I) Temporary diagnostics * **Force v4** to validate the hypothesis: * Start Chrome with `--host-resolver-rules="MAP localhost 127.0.0.1"` (test only), or * Add a test hostname in `/etc/hosts` pointing to `127.0.0.1` and use that consistently, or * Disable IPv6 *briefly* (`sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1`) just to confirm the failure is v6-related (re-enable right after). # Step-by-step troubleshooting plan 1. Reproduce with DevTools open * Attempt the fork/proxy action; screenshot any **Network** errors and the exact failing URL. * If the error mentions **PNA**, **CORS**, or **mixed content**, skip to steps 3–4. 2. Verify local stack parity * Run the `curl --ipv4/--ipv6` tests and `ss -ltnp` to see if your local wiki (and any front proxy) listens on v4 and v6. * Fix binds/listeners until both connect cleanly. 3. Ensure the browser only talks to the page’s origin * Confirm the flow uses the origin’s proxy endpoint (and not `http://localhost` directly). If you see requests to `http://127.0.0.1` or `http://[::1]` in Network, that’s the problem—refactor/enable the proxy path. 4. Align schemes (HTTPS) * If the remote site is HTTPS, verify no direct `http://localhost` calls originate from the page. If unavoidable, terminate at the origin proxy and forward server-side. 5. Normalize addresses * Pick **one**: `localhost` (preferred), or `127.0.0.1`, or `[::1]`. Use it everywhere in config and UI to keep cookies/origins consistent. 6. Retest * Repeat the fork; if it works with IPv4 but fails with IPv6 literals, keep dual-stack but pin UI/config to `localhost` (which your system resolves to both) and ensure listeners accept both families. 7. Still stuck? Collect a minimal packet & header trace * `curl -v` against both origins to collect headers. * Share the DevTools error text, the exact URLs involved, and your listener info (`ss -ltnp`)—that’s enough to pinpoint whether it’s a browser block, an origin/proxy routing issue, or a bind problem. --- If you can paste a DevTools error line (e.g., “Preflight to private network…”, “Mixed content…”, or a plain `net::ERR_CONNECTION_REFUSED` to `[::1]`), I’ll map it to the exact fix in your stack (Node, Caddy/Nginx, or wiki config) and give you the concrete config snippets next. [1]: https://fed.wiki.org/view/welcome-visitors/view/where-pages-live?utm_source=chatgpt.com "Where Pages Live - Visitors - Wiki.org"
–– ChatGPT 5 ![]()

Juergen's screenshot
assets
pages/ipv6-proxy-troubleshooting
roster
dm6.dreyeck.ch wiki.ralfbarkow.ch