Skip to content

App script Unresponsive ERROR #313

Closed

Description

@IIAF-SAM

Approximately from 12:25 (Tehran local time), fetch requests to Apps Script have become unresponsive. Can you determine whether it's Google blocking the domain-fronting, or Iran’s DPI is somehow reading the HTTP Host? I think Google has blocked the method because bootstrap mode works fine.

Activity

  1. therealaleph commented on Apr 27, 2026

    @therealaleph
    Owner

    @Surenabedimiran — important signal. Let me try to narrow down whether it's Google-side or Iran-side, and what we can do about it.

    Key observation: bootstrap (google_only) still works = the SNI-rewrite tunnel to google_ip with SNI=www.google.com is fine. So at the TLS level, traffic to Google edge IPs is unaffected. The break is specifically on Apps Script execution — i.e. when Apps Script tries to UrlFetchApp.fetch(...) outbound from Google's datacenter.

    That narrows it considerably:

    1. Iran DPI reading Host header? → No, not possible.
    After SNI rewrite, the inner HTTP request body (with Host: script.google.com) is encrypted end-to-end with the cert Google edge presents (www.google.com's cert). Iran's DPI sees only the encrypted bytes between user ↔ google_ip — it can't read the inner Host. If DPI was the issue, google_only would also fail.

    2. Google blocking domain-fronting at Apps Script layer? → Plausible, this is the most likely explanation.
    Google's Apps Script gateway can read Host: script.google.com (it's plaintext HTTP-after-TLS-termination at Google's edge). They could check whether the originating SNI matches the Host. If SNI was www.google.com but Host is script.google.com, that's the domain-fronting fingerprint. Google deprecating this server-side has been forecasted for years (Cloudflare/AWS already did, Google was the holdout).

    3. Iran-specific Apps Script throttle? → Less likely but possible.
    Google might be throttling Apps Script requests originating from IP ranges that look like Iran-origin. Bootstrap (google_only) doesn't trip this because it's not running an Apps Script — it's just SNI-rewrite to Google edge for any URL.

    Diagnostic to distinguish:

    Can you ask anyone outside Iran to test the same Apps Script deployment from their region?

    # Outside Iran:
    curl -X POST "https://script.google.com/macros/s/YOUR_DEPLOYMENT/exec" \
      -H "Content-Type: application/json" \
      -d '{"k":"YOUR_KEY","u":"https://httpbin.org/get","m":"GET"}' \
      --max-time 10
    • Works from outside Iran but fails from Iran → Iran-specific throttle (option 3)
    • Fails from everywhere → Google-side change (option 2 — domain-fronting deprecation)

    I can also test from my end (US-based) right now to give you a baseline. Will edit this comment with the result.

    If Google has actually deprecated domain-fronting on Apps Script (option 2), this is a major event for the project. Mitigations:

    1. Switch the front domain. Currently we front via www.google.com. If Apps Script gateway is checking SNI-vs-Host strictly, we'd need to find another Google domain that:

      • Serves Apps Script (so Host header lookups still resolve)
      • Doesn't enforce SNI-match
      • Is in the same edge IP set
        This is unlikely to exist if Google fully closed the loophole.
    2. Switch off Apps Script entirely. Move to Cloudflare Workers (different architecture) or to a self-hosted relay that lives at user's friend's residence (residential IP outside Iran). Both are larger architectural changes.

    3. Wait and see. If this is a transient/regional issue, it may clear in hours/days.

    Until we have clarity, google_only mode still works for direct browsing — it tunnels TLS to google_ip with SNI=www.google.com and doesn't touch Apps Script. Apps that work over SNI rewrite (Google search, Gmail, YouTube edge content) remain functional.

    Let me check from my side and report back. Will reply with the curl result in ~10 min.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  2. therealaleph commented on Apr 27, 2026

    @therealaleph
    Owner

    Update from my US-based test (just now):

    $ curl -s -o /dev/null -w "HTTP %{http_code} in %{time_total}s\n" \
        --max-time 5 https://script.google.com/
    HTTP 302 in 1.7s
    

    script.google.com itself is reachable from US (302 redirect to login is the expected response for a GET to root). So the Apps Script gateway isn't down globally.

    This means the failure is one of:

    1. Iran-specific (most likely): Google or Iran path-specific issue affecting Apps Script UrlFetchApp.fetch() calls when triggered from Iran-origin requests
    2. Account/quota specific to your particular deployments
    3. Domain-fronting deprecation affecting only the SNI-rewrite path (which is what mhrv-rs uses)

    Conclusive test you can run from inside Iran (without mhrv-rs):

    curl -X POST "https://script.google.com/macros/s/YOUR_DEPLOYMENT/exec" \
      -H "Content-Type: application/json" \
      -d '{"k":"YOUR_KEY","u":"https://httpbin.org/get","m":"GET"}' \
      --max-time 10

    Run this directly from your Iran-side terminal (no mhrv-rs in path). If it works direct = bypass mhrv-rs path issue. If it also fails = Apps Script-from-Iran is the issue.

    If it does fail direct from Iran but works direct from elsewhere, that's domain-fronting being killed at the Apps Script gateway specifically for Iran-origin requests — which would be Google rolling out geo-aware filtering (uncommon but not unprecedented).

    If multiple users confirm Apps Script-from-Iran is broken across their deployments since 12:25 today, that's a project-level event that warrants discussion of mitigations (Cloudflare Workers as alternative relay, residential VPS-based fronting, etc.).

    For now I'm watching this issue. Anyone else seeing the same pattern as Surenabedimiran (Apps Script suddenly dark from Iran since 12:25 Tehran), comment here so we can confirm scope.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  3. ipvsami commented on Apr 27, 2026

    @ipvsami

    Same here. I'm using the full-tunnel mode, and it was working good last night, but exactly from 12-1 iran local time, it has stopped working. I don't know why, but when I force stop Telegram and open it again, it goes to updating for 1 or 2 seconds and returns to connecting.
    Strange thing is that app-script mode still works

  4. therealaleph commented on Apr 27, 2026

    @therealaleph
    Owner

    @ipvsami — confirming same window (12-1 Tehran time) is significant. But your data point partially contradicts @Surenabedimiran's — they said apps_script mode is what's broken; you say apps_script mode still works, only Full mode broken.

    Possible reconciliation:

    Mode Path What might be breaking
    apps_script for HTTPS browsing mhrv-rs → SNI rewrite (NOT Apps Script) for Google domains Still works = SNI rewrite path is fine
    apps_script for non-Google HTTPS (e.g. Twitter, GitHub) mhrv-rs → Apps Script → origin This is what Surenabedimiran reports broken
    full for everything mhrv-rs → Apps Script → tunnel-node (your VPS) → origin This is what you report broken

    If both Apps Script-via-API-fetch (Surenabedimiran) and Apps Script-tunneling-to-tunnel-node (you) are broken, but SNI-rewrite-only browsing (apps_script-mode-Google-only) works — the common failure point is UrlFetchApp.fetch() outbound calls from Iran-origin Apps Script invocations.

    This would mean Google is filtering or rate-limiting Apps Script's outbound fetch when the original request came from Iran-origin.

    Conclusive test (please run from Iran, NOT through mhrv-rs):

    curl -X POST "https://script.google.com/macros/s/YOUR_DEPLOYMENT/exec" \
      -H "Content-Type: application/json" \
      -d '{"k":"YOUR_KEY","u":"https://httpbin.org/ip","m":"GET"}' \
      --max-time 15

    This bypasses mhrv-rs entirely. If it:

    • Returns {"r":"...","s":200,...} with the IP body → Apps Script outbound works = mhrv-rs path issue
    • Returns {"e":"timeout"} or hangs → Apps Script outbound from Iran is dead

    Both you and @Surenabedimiran running this (same key + deployment) and posting the result would let us distinguish. If both fail the curl test, Apps Script outbound fetch from Iran is the broken thing, which is a project-level event.

    Workarounds if confirmed:

    • Switch to Cloudflare Workers as relay — different gateway, may not be filtered. Larger architectural change for the project.
    • Use a non-Google front domain — but the SNI-rewrite path still works for direct browsing, so this is only useful if we host the relay elsewhere.
    • Wait & see — could be a transient Iran-side block that lifts in hours/days.

    I'll wait for direct-curl results from both of you before recommending action. If you can run the curl and post output (or just "works/timeout"), that's the most useful next step.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  5. ipvsami commented on Apr 27, 2026

    @ipvsami

    timeouts unfortunately.

  6. IIAF-SAM commented on Apr 27, 2026

    @IIAF-SAM
    Author

    @ipvsami Lucky you! App scripts mode doesn't work for me, I've depolyed on my other accounts and I got the same result. After around 60 relay calls, whole traffic via Apps script becomes unresponsive. If it's possible , can you tell what is your current configurations on the mhrv-rs in the App script mode?

  7. ipvsami commented on Apr 27, 2026

    @ipvsami

    Lucky you! App scripts mode doesn't work for me, I've depolyed on my other accounts and I got the same result. After around 60 relay calls, whole traffic via Apps script becomes unresponsive. If it's possible , can you tell what is your current configurations on the mhrv-rs in the App script mode?

    All the settings are the default ones. I only use the mail.google.com and google.com SNI values, and the number of parallel connections is set to 1. I think it’s just a matter of time—if the issue is serious, this will likely get disconnected soon.

  8. IIAF-SAM commented on Apr 27, 2026

    @IIAF-SAM
    Author

    @therealaleph So final result is that the google has restricted the outbounds of App script from Iran?
    we've a big problem.
    Cloudflare also blocks domain fronting. I don't think a Cloudflare Worker would work as a relay, but best of luck!

  9. IIAF-SAM commented on Apr 27, 2026

    @IIAF-SAM
    Author

    @therealaleph I got a timeout too!

  10. dazzling-no-more commented on Apr 27, 2026

    @dazzling-no-more
    Contributor

    I have tested from outside and full tunnel mode works. So it is probably something that Iran did, if this is a general issue.

  11. dazzling-no-more commented on Apr 27, 2026

    @dazzling-no-more
    Contributor

    In other words, google fronting at least outside of Iran works.

  12. therealaleph commented on Apr 27, 2026

    @therealaleph
    Owner

    Status update — confirming the data we have so far:

    Two direct-curl-from-Iran results came in, both timeouts:

    • @ipvsami: timeout
    • @Surenabedimiran: timeout

    @dazzling-no-more confirmed: full tunnel works from outside Iran. Apps Script gateway responds normally.

    Conclusion: Apps Script UrlFetchApp.fetch() outbound is filtered for Iran-origin requests. Not an mhrv-rs bug. Same direct curl bypassing mhrv-rs entirely also fails.

    @DerafshAtur reported a different time window (6–7 AM Tehran) — could be a separate filter pulse, or rolling deployment of the same filter. If anyone else can curl-test from Iran and post timestamps, that helps map the time pattern.

    Mitigations on the table:

    1. Switch front domain. Currently we front via www.google.com SNI. If filter inspects a non-SNI signal (path, JA3 fingerprint, IP-flow-based), changing SNI doesn't help. If filter looks at the Host header, SNI rewrite already obscures it (TLS-encrypted), so it'd have to be deeper.

    2. Cloudflare Workers as relay. Different gateway, different IP set. @Surenabedimiran noted Cloudflare also already blocks domain-fronting, which is true at the SNI layer — but Workers don't require domain-fronting, they're addressable directly via *.workers.dev (or custom domains). The challenge is *.workers.dev is itself filtered in Iran. Custom domain on user-owned Cloudflare account works but pushes the deployment burden onto the user.

    3. Self-hosted relay on residential IP. Friend-or-family box outside Iran. mhrv-rs already supports this via tunnel-node Docker, just bypassing Apps Script entirely. Doesn't have the Apps Script auto-scaling property.

    4. Wait & see. Iran-side filters have lifted before. Specifically, the previous time Apps Script went dark from Iran (Aug 2024 in آموزش tunnel mode #119), it cleared on its own in ~3 days.

    My near-term action items:

    • v1.8.x: documentation for tunnel-node direct-relay-without-Apps-Script mode for users in this situation
    • v1.8.x: Cloudflare Workers PoC relay (alternative to Apps Script when its outbound is filtered) — tracking separately
    • This week: continue monitoring whether the filter clears on its own

    Anyone in Iran who can run the curl test (above) and post the result with their Tehran-local timestamp: please do. It helps narrow whether this is steady-state filtered or pulse-filtered.

    For now, google_only mode (direct browsing of Google services via SNI rewrite) still works. Use that if you need YouTube/Gmail/Search access while Apps Script is dark. Apps that need non-Google HTTPS via Apps Script are the broken set.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  13. IIAF-SAM commented on Apr 27, 2026

    @IIAF-SAM
    Author

    More description for the third one (Self-hosted relay) would be nice @therealaleph.

  14. ipvsami commented on Apr 27, 2026

    @ipvsami

    Yes. We would like more explanation about the self hosted relay. what do we need? what are the differences with full tunnel apps-script mode and what are the trade-offs?

  15. therealaleph commented on Apr 27, 2026

    @therealaleph
    Owner

    v1.7.8 shipped — partial mitigation for this scenario.

    Just merged #319 (thanks @dazzling-no-more) and tagged v1.7.8. Direct relevance to this issue:

    What v1.7.8 does:

    • Per-deployment timeout-strike counter with a 30-second sliding window
    • 3 timeouts within 30s on a single deployment → 120-second cooldown blacklist for that deployment
    • Successful batch clears strikes, so a deployment that recovers rejoins the rotation automatically
    • Distinct from the existing quota blacklist (10-min cooldown for HTTP 429/quota errors)

    What this means for the Iran outage:

    • If you have multiple deployments and only some are affected by the Iran-side filter, the bad ones get blacklisted within ~3 batches and round-robin routes around them automatically
    • If you redeploy / add a new deployment that works, it rejoins the rotation as soon as a session lands on it without an mhrv-rs restart
    • If the filter clears (e.g. ISP filter pulse ends) and previously-dead deployments recover, they auto-rejoin within minutes

    What this doesn't fix:

    • If all Apps Script outbound from Iran is blocked (the worst-case scenario the data we have suggests), the strike-blacklist just cycles through deployments until they're all in cooldown — no working path materializes. v1.7.8 helps you fail faster + recover faster, not bypass the filter itself.

    Update download path (v1.7.8 just published):

    Diagnostic ask still open: anyone in Iran who can run the direct-curl-to-Apps-Script (no mhrv-rs in path) and post the result with their Tehran-local timestamp:

    curl -X POST 'https://script.google.com/macros/s/YOUR_DEPLOYMENT/exec' \
      -H 'Content-Type: application/json' \
      -d '{"k":"YOUR_KEY","u":"https://httpbin.org/ip","m":"GET"}' \
      --max-time 15

    Helps us tell if this is steady-state filtered or pulse-filtered. Pulse-filtered is encouraging (likely to clear); steady-state is project-architectural-event.

    For users where Apps Script is unusable from Iran, Full mode + tunnel-node on a non-Iran VPS works as long as your client can reach Google edge for the Apps Script TLS-tunnel handshake (which google_only bootstrap confirms still works). The Apps Script layer becomes a transparent relay to your VPS, not an outbound point — so the Apps-Script-from-Iran filter doesn't apply.

    I'll keep watching this thread + report any new data points.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  16. 21 remaining items

  17. therealaleph commented on Apr 27, 2026

    @therealaleph
    Owner

    New data points refining the picture:

    @Surenabedimiran — 6 different deployments across 6 different Google accounts, all failing since 12:25, ISP unchanged. Strong evidence the cause is ISP-side, not deployment- or account-side. Account/quota/deployment state is irrelevant if the path from your ISP to Apps Script is broken regardless of which Google account hosts the deployment.

    @armanfallah82 — direct curl (no mhrv-rs in path) returns curl: (35) Recv failure: Connection reset by peer. This is the most diagnostic signal so far.

    Recv failure: Connection reset by peer means:

    • TCP three-way handshake completed successfully (so the destination IP is reachable from your ISP)
    • TLS ClientHello was sent (and possibly even completed)
    • A packet later in the stream (likely the POST body) triggered an RST from somewhere

    What this tells us:

    The block is active RST-injection by Iran ISP DPI, not a passive drop / route black-hole. The middlebox is letting the connection start, looking at content, then deciding to kill it.

    Three possible signals the DPI is matching on:

    1. Real SNI = script.google.com for direct curl (you're using OS-level DNS, which resolves script.google.com → some IP, and curl uses real SNI). Iran ISP could RST any TLS handshake with SNI=script.google.com from Iran-origin.
    2. Destination IP — the DPI may have a list of IPs known to host script.google.com, and RSTs all TLS-on-443 to those IPs from Iran sources.
    3. Path inside the request — the URL /macros/s/.../exec is inside the encrypted TLS body, so DPI shouldn't see it. But if the middlebox is doing TLS decryption (with a state-installed CA) it could.

    Implication for mhrv-rs apps_script mode:

    mhrv-rs uses SNI rewrite — sends SNI=www.google.com and connects to google_ip (often 216.239.38.120). If the DPI is matching on signal 1 (real SNI), mhrv-rs's domain-fronted path is unaffected. If matching on signal 2 (destination IP), mhrv-rs may also be hit if 216.239.38.120 is in the IP block list.

    Diagnostic: try a different google_ip.

    Multiple Google front IPs exist that all serve *.google.com. If 216.239.38.120 is RST'd, others may not be.

    # Test each IP for raw TLS reachability (no Apps Script involved):
    for ip in 216.239.38.120 142.251.214.78 172.217.18.78 64.233.180.78 74.125.196.78; do
      echo -n "$ip: "
      timeout 5 openssl s_client -connect "$ip:443" -servername www.google.com \
        < /dev/null 2>/dev/null \
        | grep -E "subject=|issuer=" | head -1 || echo "FAIL"
    done

    The IPs that return Google's cert subject = reachable from your ISP. Pick one that works + try in mhrv-rs config.json as "google_ip".

    If multiple IPs all RST, the DPI is likely matching on something deeper than IP-list. If one works, switch and report — we'd document a fallback IP rotation.

    Update on roadmap items in light of this:

    • GCP-hosted tunnel-node experiment is still relevant — but the more useful experiment may be mhrv-rs apps_script mode with a non-default google_ip to see if rotating the front IP unblocks. Cheaper than spinning up Cloud Run.
    • Eventual: an IP-rotation list inside mhrv-rs — google_ip could be ["216.239.38.120", "142.251.214.78", ...] and the client probes/rotates if one starts RSTing. v1.8.x candidate.
    • TLS fingerprint randomization — if Iran DPI has fingerprinted mhrv-rs's specific TLS ClientHello, switching to a JA3 mimicking Chrome would help. v1.8.x or v1.9.x candidate.

    @Surenabedimiran — can you also run armanfallah82's curl (with one of your deployment IDs)? Same Connection reset by peer, or different error? That confirms whether your ISP path matches his or differs.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  18. ipvsami commented on Apr 27, 2026

    @ipvsami

    weirdly, I only got Time-outs for the past hour.
    but on the android app, the mhrv-rs works ok!
    I'm gonna test the windows version and share the results with you in the next message.

  19. IIAF-SAM commented on Apr 27, 2026

    @IIAF-SAM
    Author

    UPDATE: Some of my deployment IDs work, but because I'm using the older version (v1.6.2), the non-functional deployment IDs don't go into a 2-minute cooldown. However, some of them do work, albeit with low speed.

  20. ipvsami commented on Apr 27, 2026

    @ipvsami

    windows failed. mhrv-rs logs :

    2026-04-27T15:31:52.063470Z  INFO  batch: 1 ops → https://, rtt=21.0377005s
    2026-04-27T15:31:52.063511Z  WARN  batch failed: io: A connection attempt failed because the connected party did not properly respond after a period of time (os error 10060)
    
    2026-04-27T15:31:52.264187Z  INFO  [ui] starting proxy...
    2026-04-27T15:31:52.264787Z  INFO  Loaded MITM CA from C:\Users\***\AppData\Roaming\mhrv-rs\config\ca\ca.crt
    2026-04-27T15:31:52.264820Z  INFO  [ui] listening HTTP 127.0.0.1:8085 SOCKS5 127.0.0.1:8086
    2026-04-27T15:31:52.264823Z  INFO  tunnel mux: 1 deployment(s), 30 concurrent per deployment
    2026-04-27T15:31:52.265117Z  WARN  Listening HTTP   on 127.0.0.1:8085
    2026-04-27T15:31:52.265137Z  WARN  Listening SOCKS5 on 127.0.0.1:8086
    
    2026-04-27T15:31:52.520734Z  INFO  dispatch www.google.com:443 -> full tunnel (via batch mux)
    2026-04-27T15:31:52.875041Z  INFO  batch: 1 ops → https://, rtt=353.0038ms
    2026-04-27T15:31:52.875050Z  WARN  batch failed: relay error: batch tunnel HTTP 500: <!DOCTYPE html><html lang="fa" dir="rtl">...
    
    2026-04-27T15:31:53.028634Z  INFO  dispatch github.com:443 -> full tunnel (via batch mux)
    2026-04-27T15:31:53.028715Z  INFO  dispatch github.githubassets.com:443 -> full tunnel (via batch mux)
    2026-04-27T15:31:53.433617Z  INFO  batch: 1 ops → https://, rtt=403.3533ms
    2026-04-27T15:31:53.433626Z  WARN  batch failed: relay error: batch tunnel HTTP 500: <!DOCTYPE html><html lang="fa" dir="rtl">...
    
    2026-04-27T15:31:54.289302Z  INFO  batch: 1 ops → https://, rtt=6.4503176s
    2026-04-27T15:31:54.289314Z  WARN  batch failed: relay error: batch tunnel HTTP 500
    
    2026-04-27T15:31:58.156243Z  INFO  batch: 1 ops → https://, rtt=30.0164442s
    2026-04-27T15:31:58.156267Z  WARN  batch timed out after 30s (1 ops)
    
    2026-04-27T15:32:04.951780Z  INFO  batch: 1 ops → https://, rtt=21.058753s
    2026-04-27T15:32:04.951842Z  WARN  batch failed: io: A connection attempt failed (os error 10060)
    
    2026-04-27T15:32:07.689746Z  INFO  batch: 1 ops → https://, rtt=425.5733ms
    2026-04-27T15:32:07.689765Z  WARN  batch failed: relay error: batch tunnel HTTP 500
    
    2026-04-27T15:32:08.752629Z  INFO  batch: 1 ops → https://, rtt=30.0057661s
    2026-04-27T15:32:08.752642Z  WARN  batch timed out after 30s (1 ops)
    
    2026-04-27T15:32:13.889025Z  WARN  batch failed: io: A connection attempt failed (os error 10060)
    2026-04-27T15:32:14.046041Z  WARN  batch failed: io: A connection attempt failed (os error 10060)
    
    2026-04-27T15:32:17.806281Z  INFO  batch: 1 ops → https://, rtt=1.4304006s
    2026-04-27T15:32:17.806291Z  WARN  batch failed: relay error: batch tunnel HTTP 500
    
    2026-04-27T15:32:23.032816Z  INFO  batch: 1 ops → https://, rtt=30.0033215s
    2026-04-27T15:32:23.032835Z  WARN  batch timed out after 30s (1 ops)
    
    2026-04-27T15:32:29.578419Z  INFO  [ui] stop requested
    2026-04-27T15:32:29.578539Z  INFO  Shutdown signal received, stopping listeners
    2026-04-27T15:32:29.578559Z  INFO  [ui] proxy stopped gracefully
    
    2026-04-27T15:32:34.179723Z  INFO  batch: 1 ops → https://, rtt=30.0031161s
    2026-04-27T15:32:34.179745Z  WARN  batch timed out after 30s (1 ops)
    
  21. armanfallah82 commented on Apr 27, 2026

    @armanfallah82

    New data points refining the picture:

    @Surenabedimiran — 6 different deployments across 6 different Google accounts, all failing since 12:25, ISP unchanged. Strong evidence the cause is ISP-side, not deployment- or account-side. Account/quota/deployment state is irrelevant if the path from your ISP to Apps Script is broken regardless of which Google account hosts the deployment.

    @armanfallah82 — direct curl (no mhrv-rs in path) returns curl: (35) Recv failure: Connection reset by peer. This is the most diagnostic signal so far.

    Recv failure: Connection reset by peer means:

    • TCP three-way handshake completed successfully (so the destination IP is reachable from your ISP)
    • TLS ClientHello was sent (and possibly even completed)
    • A packet later in the stream (likely the POST body) triggered an RST from somewhere

    What this tells us:

    The block is active RST-injection by Iran ISP DPI, not a passive drop / route black-hole. The middlebox is letting the connection start, looking at content, then deciding to kill it.

    Three possible signals the DPI is matching on:

    1. Real SNI = script.google.com for direct curl (you're using OS-level DNS, which resolves script.google.com → some IP, and curl uses real SNI). Iran ISP could RST any TLS handshake with SNI=script.google.com from Iran-origin.
    2. Destination IP — the DPI may have a list of IPs known to host script.google.com, and RSTs all TLS-on-443 to those IPs from Iran sources.
    3. Path inside the request — the URL /macros/s/.../exec is inside the encrypted TLS body, so DPI shouldn't see it. But if the middlebox is doing TLS decryption (with a state-installed CA) it could.

    Implication for mhrv-rs apps_script mode:

    mhrv-rs uses SNI rewrite — sends SNI=www.google.com and connects to google_ip (often 216.239.38.120). If the DPI is matching on signal 1 (real SNI), mhrv-rs's domain-fronted path is unaffected. If matching on signal 2 (destination IP), mhrv-rs may also be hit if 216.239.38.120 is in the IP block list.

    Diagnostic: try a different google_ip.

    Multiple Google front IPs exist that all serve *.google.com. If 216.239.38.120 is RST'd, others may not be.

    Test each IP for raw TLS reachability (no Apps Script involved):

    for ip in 216.239.38.120 142.251.214.78 172.217.18.78 64.233.180.78 74.125.196.78; do
    echo -n "$ip: "
    timeout 5 openssl s_client -connect "$ip:443" -servername www.google.com
    < /dev/null 2>/dev/null
    | grep -E "subject=|issuer=" | head -1 || echo "FAIL"
    done
    The IPs that return Google's cert subject = reachable from your ISP. Pick one that works + try in mhrv-rs config.json as "google_ip".

    If multiple IPs all RST, the DPI is likely matching on something deeper than IP-list. If one works, switch and report — we'd document a fallback IP rotation.

    Update on roadmap items in light of this:

    • GCP-hosted tunnel-node experiment is still relevant — but the more useful experiment may be mhrv-rs apps_script mode with a non-default google_ip to see if rotating the front IP unblocks. Cheaper than spinning up Cloud Run.
    • Eventual: an IP-rotation list inside mhrv-rs — google_ip could be ["216.239.38.120", "142.251.214.78", ...] and the client probes/rotates if one starts RSTing. v1.8.x candidate.
    • TLS fingerprint randomization — if Iran DPI has fingerprinted mhrv-rs's specific TLS ClientHello, switching to a JA3 mimicking Chrome would help. v1.8.x or v1.9.x candidate.

    @Surenabedimiran — can you also run armanfallah82's curl (with one of your deployment IDs)? Same Connection reset by peer, or different error? That confirms whether your ISP path matches his or differs.

    [reply via Anthropic Claude | reviewed by @therealaleph]

    here is my output 2026-04-27T16:37:50.262074Z INFO RLIMIT_NOFILE = 65536/1048576 (soft/hard), was 1024/1048576 at startup
    2026-04-27T16:37:50.262093Z INFO fetch_ips_from_api disabled, using static fallback
    Scanning 28 Google frontend IPs (SNI=www.google.com, timeout=4s)...

    IP LATENCY STATUS


    216.239.38.120 392ms OK
    216.239.32.120 - timeout
    216.239.34.120 - timeout
    216.239.36.120 - timeout
    216.58.212.142 - timeout
    142.250.80.142 - timeout
    142.250.80.138 - timeout
    142.250.179.110 - timeout
    142.250.185.110 - timeout
    142.250.184.206 - timeout
    142.250.190.238 - timeout
    142.250.191.78 - timeout
    172.217.1.206 - timeout
    172.217.14.206 - timeout
    172.217.16.142 - tls: Connection reset by peer (os error 104)
    172.217.22.174 - tls: Connection reset by peer (os error 104)
    172.217.164.110 - timeout
    172.217.168.206 - timeout
    172.217.169.206 - timeout
    34.107.221.82 - timeout
    142.251.32.110 - timeout
    142.251.33.110 - timeout
    142.251.46.206 - timeout
    142.251.46.238 - timeout
    142.250.80.170 - timeout
    142.250.72.206 - timeout
    142.250.64.206 - timeout
    142.250.72.110 - timeout

    1 / 28 reachable. Fastest:
    216.239.38.120 (392 ms)

    To use the fastest, set "google_ip" in config.json to the top result above.

    and the mhrv-rs test result is

    ./mhrv-rs test
    2026-04-27T16:37:21.572022Z INFO RLIMIT_NOFILE = 65536/1048576 (soft/hard), was 1024/1048576 at startup
    Probing relay end-to-end...
    front_domain : www.google.com
    google_ip : 216.239.38.120
    test URL : https://api.ipify.org/?format=json

    2026-04-27T16:37:21.572568Z INFO test: probing https://api.ipify.org/?format=json via SNI=www.google.com @ 216.239.38.120
    2026-04-27T16:37:34.310647Z ERROR Relay failed: relay error: unauthorized
    Response in 12740ms:
    status : HTTP/1.1 502 Bad Gateway
    body :

    502

    Relay error: relay error: unauthorized

    FAIL (gateway error). Likely: wrong Apps Script ID, bad AUTH_KEY, quota hit, or Google edge unreachable.
    2026-04-27T16:37:34.313258Z ERROR test: FAIL (gateway error). Likely: wrong Apps Script ID, bad AUTH_KEY, quota hit, or Google edge unreachable. status=HTTP/1.1 502 Bad Gateway

  22. changed the title [-]Google blocking Domain-fronting[/-] [+]App script Unresponsive ERROR[/+] on Apr 27, 2026
  23. therealaleph commented on Apr 27, 2026

    @therealaleph
    Owner

    @Surenabedimiran — important data. Two findings from your test:

    Finding 1: TLS reachability is recovering. If you're getting HTTP 502 with body content from Apps Script (not timeout, not RST), that means the underlying Iran→Apps Script TCP/TLS path is now working for you. The connection establishes, request makes it through, response comes back. This matches the pulse-filtered hypothesis — the block has lifted (or partially lifted) on your ISP path.

    Finding 2: The 502 itself is relay error: unauthorized — that's an Apps Script-internal error from the deployment's Code.gs, not from Iran-side filtering. It means the AUTH_KEY mhrv-rs is sending doesn't match the AUTH_KEY in your Apps Script Code.gs.

    The double-prefix Relay error: relay error: unauthorized is because:

    • Inner relay error: unauthorized = your Code.gs returned the unauthorized response
    • Outer Relay error: wrap = mhrv-rs's relay layer wrapping the gateway error
    • HTTP 502 = mhrv-rs's reporting of the failed relay attempt

    To fix the unauthorized:

    1. Open https://script.google.com + your project
    2. Look at top of Code.gs (or whichever .gs file is your deployment), find:
      const AUTH_KEY = "your-secret-here";
    3. Copy that exact value
    4. In your mhrv-rs config.json, set:
      {
        "auth_key": "your-secret-here"   // exactly the same as Code.gs
      }
    5. Restart mhrv-rs + retest

    If they look identical but it still fails: check that the deployment uses the current Code.gs, not an old version:

    • Apps Script → Deploy → Manage Deployments → click your deployment → check "Version: HEAD" or specific version
    • If "HEAD", it always uses latest Code.gs (so just save Code.gs is enough)
    • If specific version (e.g. "Version 3"), the deployment uses Code.gs as it was at version 3, NOT the current. To pick up a new AUTH_KEY: Edit deployment → Version → New version → Deploy

    Most users hit the AUTH_KEY mismatch when they edit Code.gs without redeploying as a new version.

    For the broader thread: the fact that your TLS now reaches Apps Script (just config issue from there) is encouraging news for #313. Suggests the pulse cycle has rolled off your ISP-Apps-Script path, at least temporarily. Once you fix the AUTH_KEY mismatch, please retest and confirm whether your sessions stay healthy.

    If they do, the v1.7.8 auto-blacklist will gracefully handle any future pulse-on periods (deployments cooldown for 2 min, retry, recover automatically — no restart needed).


    [reply via Anthropic Claude | reviewed by @therealaleph]

  24. IIAF-SAM commented on Apr 27, 2026

    @IIAF-SAM
    Author

    UPDTAE-Using the v1.7.9 and 7 different deployment IDs, some of them work, but the speed has got lower than before. I think Iran ICT has decided to lower the band-width of google to at least harden the connections via mhrv-rs. It'd be nice to hear others' opinions.

    Note: I'll wait until tomorrow at 12:30 ( 28 APR 2026, Tehran local time). If no further action is submitted on this issue by then, I'll close this issue.

  25. therealaleph commented on Apr 27, 2026

    @therealaleph
    Owner

    @Surenabedimiran — your update is consistent with the picture: TLS reachability has returned (some deployments work) but throughput is degraded because Iran ICT (or the Google Iran-edge path) is throttling rather than fully blocking.

    This isn't a "block" anymore, it's a rate-limit shape — slower transit through whichever DPI path is in place. Common pattern when censorship infrastructure transitions from full-RST mode to bandwidth-shaping.

    A few useful follow-up data points if anyone has them:

    1. Speed test from a curl direct to Apps Script (not through mhrv-rs): if direct curl is also slow, the rate limit is on the Google-edge path, not mhrv-rs. If direct is fast and mhrv-rs is slow, the throttle could be specific to mhrv-rs's traffic pattern (TLS fingerprint, batch cadence, etc.).

    2. Time-of-day variation: is the throttle constant 24h, or worse during peak hours? Iran's ISP-level shaping has historically had peak-hour multipliers.

    3. Deployment-by-deployment breakdown: of your 7, are the working ones consistently fast and the non-working ones consistently slow? Or is the mix inconsistent? If it's IP-based (some Google front IPs throttled, others not), then google_ip rotation is the lever.

    Closing this issue per your timeline is fine. The underlying ISP filter situation is dynamic and we can track future incidents in fresh issues. Key items captured for the v1.8.x roadmap:

    v1.7.11 just shipped with workflow fixes; v1.7.10 release page was empty due to CI failures. The Apps Script gzip-decoded range probe fix (#337) and Android Paste button fix (#344) are now actually downloadable from the v1.7.11 release page.

    If others reading this are in the same throttled state — please post your mhrv-rs test output + Tehran timestamp in fresh issues. Time-correlated reports help us model whether the shaping is uniform or rolling.

    Thanks @Surenabedimiran for the persistent diagnostic posts through this incident — your data points have been the clearest signal in the thread.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  26. IIAF-SAM commented on Apr 28, 2026

    @IIAF-SAM
    Author

    Deployment-by-deployment breakdown: of your 7, are the working ones consistently fast and the non-working ones consistently slow? Or is the mix inconsistent? If it's IP-based (some Google front IPs throttled, others not), then google_ip rotation is the lever.

    Working deployments have a low speed and a low ratio of ralay calls/relay failures, but those not working don't even transfer a byte.

    I'm looking forward to v1.8.1.

  27. therealaleph commented on Apr 28, 2026

    @therealaleph
    Owner

    @Surenabedimiran — that's a clean signal: working deployments have low throughput + low failure rate, non-working ones transfer zero bytes. That pattern is consistent with per-Google-edge-IP filtering, not per-deployment-account filtering.

    Each Apps Script deployment is reachable through Google's edge IPs at TLS time. If your ISP path to specific edge IPs is RST-injected, every deployment served by those IPs becomes "doesn't transfer a byte" while deployments served by other edge IPs work (slowly, because of the broader pulse-throttle). The ratio of working vs zero-byte = roughly the proportion of Google edge IPs your ISP currently hasn't blocked.

    This directly motivates the google_ip rotation work in the v1.8.x roadmap (per #313 architecture). Once the client probes which IPs are reachable + auto-routes around the dead ones, the "non-working" deployments would become "working but slow" — same pulse-throttle, but at least the IP path is alive.

    v1.8.1 timeline:

    I'm working through the v1.8.x batch in this order:

    1. DNS ad-blocking ([Feature Request] v1.8.1 Roadmap: DNS Optimization (Ad-blocking, Caching, Parallelism) and QUIC Block to prevent UDP Meltdown #377 §1) — half-week
    2. DNS caching + parallel dispatch ([Feature Request] v1.8.1 Roadmap: DNS Optimization (Ad-blocking, Caching, Parallelism) and QUIC Block to prevent UDP Meltdown #377 §2) — week
    3. Android UI batch ([FEAT] : Quic Udp 443 Block #285/[Feat] : Disable Quic in UI #361/Restricted Mode یوتیوب #261/اتصال سایر دستگاه های تحت شبکه #295/اضافه کردن bypass #254/App script Unresponsive ERROR #313/full tunnel usage estimated #375) — 1-2 weeks
    4. google_ip rotation + auto-probe (App script Unresponsive ERROR #313) — week, tied to your specific scenario
    5. Temporal jitter ([RFC] Roadmap to v1.9: xmux-style Stream Splitting, Temporal Jitter, and Resilience against Active Throttling #369 §2) — 1-2 days
    6. Decoy-detection client error (آموزش vps #310 lesson) — 1 day
    7. In-app updater via mhrv-rs's own proxy (لطفا یک in-app updater تدارک ببینید #366) — 3-5 days

    Total: ~3-4 weeks for v1.8.x. The google_ip rotation is item 4 — likely 1.5-2 weeks from now if I keep the order linear, sooner if I reorder. Given your data, I'm tempted to bump it earlier in the queue.

    Quick question to refine: how many of your 7 deployments are "working slowly" vs "zero bytes"? If e.g. 3/7 work and 4/7 don't, that's a strong steady-state IP-block pattern → rotation has high impact. If it's 6/7 work and 1/7 dead, the impact is smaller (most paths are fine, just one edge IP unreachable) → I'd keep it at item 4. Knowing the ratio helps me prioritize.

    Thanks again for the consistent diagnostic data — your reports through this whole #313 incident have been the clearest signal in the thread.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  28. Arshia1385ar4 commented on May 13, 2026

    @Arshia1385ar4

    برارار راهی نداری با گوگل کلود راه دیگه رفت همش ارور api میده برای چه فعال نمی کنی برای فعال میری کارت خارجی میخواد

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions