Immich / Troubleshooting

Immich Upload Fails Through Cloudflare Tunnel While a Trusted Non-Tunnel Path Works

Compare the same Immich upload over a trusted non-Tunnel path and a Cloudflare Tunnel hostname, then classify a Cloudflare-attributed 413, a 524 timeout, a Tunnel origin 502, or an origin-side proxy failure before changing configuration.

By Andrey Tretyak · Sources last reviewed

Use the same asset and account on both paths first. If an already trusted non-Tunnel path succeeds while the Cloudflare Tunnel hostname fails, record the exact response and identify which layer produced it before changing Immich, the proxy, or Cloudflare settings.[1][2]

Cloudflare can impose request-size and timeout boundaries, while Immich documents separate reverse-proxy requirements for forwarded headers, upload handling, websocket upgrades, root-path serving, and its well-known endpoint. Keep those layers separate: Cloudflare-attributed evidence selects an edge branch; origin or intermediate-proxy evidence selects the Immich proxy branch.[5]

Sections

Applicability

Products
Immich
Scope
For an Immich deployment reachable both over an already trusted non-Tunnel path and through a Cloudflare Tunnel-backed hostname, where the same account and the same asset upload over the trusted non-Tunnel path but fail through the Tunnel-backed hostname with Tunnel or Cloudflare-attributed evidence. This page covers only the Cloudflare Tunnel scope; it does not cover generic orange-cloud proxy failures, background-only mobile stalls, album selection, checksum deduplication, server storage or database and queue failures, accepted uploads with missing derivatives, or a generic proxy failure with no Tunnel or Cloudflare evidence.[5][1][2]
Last verified

Symptoms

  • The same asset and account upload over the already trusted non-Tunnel path, but the identical attempt through the Cloudflare Tunnel-backed hostname fails or never completes. The Tunnel path returns a Tunnel or Cloudflare-attributed response such as an attributed HTTP 413, an HTTP 524, or a Tunnel 502 stating the origin cannot be reached. A bare HTTP 413 alone does not prove a Cloudflare limit; the producer must be attributed before any plan-limit branch is entered.[5][1][2]

Quick diagnosis

Prove the same asset works over an already trusted non-Tunnel path before blaming the Tunnel path, then attribute the exact response before any plan or timeout branch.

Read-only

Reproduce with the same asset on both paths

Upload the same asset with the same account over the already trusted non-Tunnel path and through the Cloudflare Tunnel-backed hostname, recording the exact response on each. Only a non-Tunnel path that already exists and is already trusted may be used; never expose Immich directly to the Internet, open arbitrary ports, disable TLS verification, disable Tunnel security, or bypass authentication for the comparison.[5]

Read-only

Record the exact Cloudflare response

Record the exact HTTP status, the exact response wording, and the producer evidence on the failing Tunnel path: a 413 payload message with or without Cloudflare attribution, a 524 timeout message, a Tunnel 502 stating the origin service cannot be reached, or an error passed through from the origin. The producer evidence selects the branch; a remembered paraphrase does not, and a bare 413 without Cloudflare attribution never enters the plan-limit branch.[1][2][3]

Interactive troubleshooter

Your answers stay in this browser tab. The tool does not connect to your systems or send diagnostic results.

Guided check / step 1

Does the same asset work over a trusted non-Tunnel path but fail through the Cloudflare Tunnel hostname?

Confirm with the same account and asset over an already trusted non-Tunnel path and through the Cloudflare Tunnel-backed hostname. This page covers only the Tunnel scope, not generic orange-cloud proxy failures. Background-only stalls, skipped duplicates, and failures on both paths are different observations.[5][4]

Read the complete diagnostic tree without using the controls
  1. Does the same asset work over a trusted non-Tunnel path but fail through the Cloudflare Tunnel hostname?

    Confirm with the same account and asset over an already trusted non-Tunnel path and through the Cloudflare Tunnel-backed hostname. This page covers only the Tunnel scope, not generic orange-cloud proxy failures. Background-only stalls, skipped duplicates, and failures on both paths are different observations.[5][4]

    • Yes, Tunnel path only failsWhat exact response does the Tunnel path return, and who produced it?
    • No, a different observationInvestigate the actual observation
  2. What exact response does the Tunnel path return, and who produced it?

    Use the recorded status, wording, and producer evidence. A Cloudflare-attributed 413 selects the plan-limit branch; a 413 without Cloudflare attribution selects the origin or intermediate-proxy branch. A 524 selects the timeout-classification branch, never a single 125-second verdict. A Tunnel 502 about the origin selects the Tunnel handoff, and any other origin-generated error selects the origin branch.[1][2][3]

    • HTTP 413 with Cloudflare attributionA Cloudflare-attributed plan or zone body-size limit rejects the upload
    • HTTP 413 without Cloudflare attributionCheck the origin or intermediate hop for a non-Cloudflare error
    • HTTP 524 timeout messageDoes the 524 evidence point to the read side or the write side?
    • Tunnel 502, origin unreachableHand Tunnel origin evidence to the Tunnel diagnosis
    • Ordinary origin-generated errorCheck the origin or intermediate hop for a non-Cloudflare error
    • Cannot confirm the responseCollect a Tunnel-path evidence packet
  3. Does the 524 evidence point to the read side or the write side?

    A 524 covers two documented boundaries: no HTTP response within the 125-second proxy read timeout by default, or an unfinished request-body write within the 30-second proxy write timeout. Classify with origin and proxy timing; a single 524 response alone never proves which side timed out. If the sides cannot be distinguished, collect timing evidence and stop before mutation.[2]

    • Read-side timeout evidenceThe upload exceeds the classified proxy read or write timeout
    • Write-side timeout evidenceThe upload exceeds the classified proxy read or write timeout
    • Cannot distinguish the timeout sideCollect a Tunnel-path evidence packet
  4. A Cloudflare-attributed plan or zone body-size limit rejects the upload

    With Cloudflare attribution confirmed, compare the asset size with the plan maximum, 100 MB on Free and Pro, 200 MB on Business, up to 5 GB self-serve on Enterprise, and with the zone Maximum Upload Size. Resolve at the plan or zone layer with a documented remedy. A Tunnel hostname routed via the tunnel target cannot be fixed by simply switching that hostname to DNS-only; never bypass edge security as a workaround.[1]

  5. The upload exceeds the classified proxy read or write timeout

    Time the same upload against the origin over the trusted non-Tunnel path with synchronized origin and proxy timing. A read-side timeout means no HTTP response arrived within the 125-second proxy read timeout by default; a write-side timeout means the request-body write did not complete within the 30-second proxy write timeout. Fix the responsible side or change the applicable plan or configuration where Cloudflare documentation supports it; only Enterprise zones can raise the read timeout, up to 6000 seconds. If the sides cannot be distinguished, collect timing evidence and stop before mutation.[2]

  6. Hand Tunnel origin evidence to the Tunnel diagnosis

    A connected tunnel whose cloudflared cannot reach the origin belongs to the Tunnel origin diagnosis. Hand over the ingress URL and log signature; no Immich setting substitutes for an unreachable origin.[3]

  7. Check the origin or intermediate hop for a non-Cloudflare error

    An error generated by the origin or an intermediate proxy, including a 413 without Cloudflare attribution, selects the responsible hop check: forwarded headers, large-upload allowance with buffering disabled, websocket upgrades, root-path serving, and well-known routing. It never enters the Cloudflare plan-limit branch.[5]

  8. Investigate the actual observation

    Background-only stalls, skipped duplicates, album selection, storage or dependency failures, accepted uploads with missing derivatives, failures on both the Tunnel and non-Tunnel paths, and generic proxy failures with no Tunnel or Cloudflare evidence each need their own diagnosis. Both-paths failures return to the generic Immich upload diagnosis.[4]

  9. Collect a Tunnel-path evidence packet

    Preserve versions, the Cloudflare plan, the asset size, the same-asset comparison on the Tunnel and non-Tunnel paths with synchronized origin and proxy timing logs, the producer attribution evidence, and the exact response wording. Send the sanitized evidence to the operator; an unproven timeout side or an unattributed 413 never justifies a plan, zone, or routing change.[4][1][2]

Detailed diagnosis

Read-only

1. Confirm the Tunnel-only failure with the same asset

Confirm that the same account and asset succeed over the already trusted non-Tunnel path and fail through the Cloudflare Tunnel-backed hostname. If both paths fail, this page does not apply: return to the generic Immich upload diagnosis instead. If only background mobile backup stalls, that is a separate mobile-OS observation.[5][4]

Read-only

2. Identify the exact response producer

Match the recorded status, wording, and producer evidence: a Cloudflare-attributed 413 selects the plan-limit branch, while a 413 without Cloudflare attribution selects the origin or intermediate-proxy branch; 524 selects the timeout-classification branch; a Tunnel 502 stating the origin service cannot be reached selects the Tunnel origin handoff; an ordinary origin-generated error selects the origin branch. A bare HTTP 413 alone never proves a Cloudflare limit. Each producer has different evidence and a different owner.[1][2][3]

Read-only

3. For a Cloudflare-attributed 413, compare the asset size with the plan and zone limits

Enter this branch only with Cloudflare attribution evidence: documented Cloudflare 413 response wording, Cloudflare edge response evidence, Ray ID or another documented edge indicator, or a confirmed producer from synchronized proxy and origin logs. Never invent header names or guarantees; use only current official Cloudflare documentation. Then compare the failing asset's size with the Cloudflare plan maximum request body size: 100 MB on Free and Pro, 200 MB on Business, up to 5 GB self-serve on Enterprise. Then check the zone's Maximum Upload Size on the Network page, because a lowered zone value rejects requests below the plan maximum with the same 413. Without attribution, hand off to the origin or intermediate-proxy branch instead.[1]

Read-only

4. For a 524, classify read-side versus write-side timeout evidence

A 524 does not automatically mean the origin response was slower than 125 seconds. It means either the origin connection was established but no HTTP response arrived within the proxy read timeout of 125 seconds by default, or Cloudflare did not finish writing the request body to the origin within the proxy write timeout of 30 seconds, which cannot be adjusted. Only Enterprise zones can raise the read timeout, up to 6000 seconds. Confirm whether the evidence points to the read side or the write side, then time the same upload against the origin over the trusted non-Tunnel path with synchronized origin and proxy timing. If the available evidence cannot distinguish the two, collect origin and proxy timing evidence and stop before any mutation.[2]

Read-only

5. For a non-Cloudflare-attributed failure, check the origin or intermediate-proxy branch

When the response is passed through from the origin or an intermediate proxy rather than generated by Cloudflare, including a 413 without Cloudflare attribution, inspect the responsible hop against the documented Immich proxy requirements: forwarded Host, X-Real-IP, X-Forwarded-Proto, and X-Forwarded-For headers, large-upload allowance with proxy buffering disabled, websocket upgrades, root-path serving, and well-known endpoint routing.[5]

Supported scenarios

These observations narrow the next investigation; they do not establish a unique cause.

The asset exceeds the Cloudflare plan or zone body-size limit

Cloudflare rejects the upload with 413 when the request body exceeds the plan maximum: 100 MB on Free and Pro, 200 MB on Business, up to 5 GB self-serve on Enterprise. A zone Maximum Upload Size set below the asset size produces the same 413 even on a higher plan. This cause applies only after Cloudflare attribution is confirmed; a 413 from the origin, an intermediate proxy, or the application is a different cause.[1]

How to check: Confirm Cloudflare attribution evidence first, then confirm the 413 wording and compare the failing asset size with the plan maximum and the zone Maximum Upload Size value. Without attribution, use the origin or intermediate-proxy branch.[1]

The upload exceeds a Cloudflare proxy read or write timeout

Cloudflare returns 524 either when the origin connection succeeds but no HTTP response arrives within the 125-second proxy read timeout by default, or when the request-body write to the origin does not complete within the 30-second proxy write timeout, which cannot be adjusted. Only Enterprise zones can raise the read timeout, up to 6000 seconds. For upload workflows the two sides matter: a slow origin response selects the read side, while an unfinished request-body write selects the write side. A 524 never by itself proves which side timed out.[2]

How to check: Confirm the 524 wording, classify whether the evidence points to the read side or the write side, then time the same upload against the origin over the trusted non-Tunnel path with synchronized origin and proxy timing. If the evidence cannot distinguish the sides, collect timing evidence and stop before mutation.[2]

cloudflared cannot reach the Immich origin

A Tunnel 502 stating that the origin service cannot be reached means the tunnel is connected to Cloudflare but cloudflared cannot reach the origin service named in the ingress rule. That observation belongs to the Tunnel origin diagnosis, not to Immich upload logic.[3]

How to check: Confirm the Tunnel 502 wording and the connected tunnel state, then hand the ingress and log evidence to the Tunnel origin diagnosis.[3]

The responsible origin or intermediate hop violates an Immich proxy requirement

When the failure is not Cloudflare-attributed, including a 413 generated by the origin, an intermediate proxy, or the application layer, the responsible hop may drop or alter the required forwarded headers, buffer uploads, block websocket upgrades, serve a sub-path, or misroute the well-known endpoint. Each of these breaks the documented Immich proxy contract independently of Cloudflare limits.[5]

How to check: Confirm a non-Cloudflare-attributed response, then compare the hop's headers, buffering, websocket, path, and well-known routing against the documented requirements.[5]

Next actions and procedure boundaries

Potentially disruptive

Resolve a proven body-size limit at the plan or zone layer

Before changing anything

Risk
Plan and zone changes affect every client behind the Tunnel-backed hostname, not only the failing upload. A wrong zone or plan change can break all remote access instead of fixing one upload.[1]
Safer check
Confirm Cloudflare attribution evidence and the 413 wording, record the asset size, the plan maximum, and the current zone Maximum Upload Size before changing anything.[1]
Expected result
After the change, the same asset uploads through the Tunnel-backed hostname while smaller assets and trusted non-Tunnel uploads keep working.[1]
Backup / recovery access
Record the prior zone and plan settings so the previous edge behavior can be restored exactly.[1]
Rollback
Restore the recorded prior zone and plan settings if uploads do not recover, then re-collect the same-asset comparison before further changes.[1]

When Cloudflare attribution is confirmed and the asset exceeds the effective request-body limit, use a remedy supported by the proven boundary: raise a deliberately lowered zone Maximum Upload Size only up to the plan maximum, use a smaller request where the application workflow legitimately supports it, upgrade the applicable plan, or use a separately designed trusted access path that does not traverse that edge limit. Never expose Immich directly to the Internet, disable Tunnel security, open arbitrary ports, disable TLS, or bypass authentication.[1]

Potentially disruptive

Resolve a proven origin timeout without touching edge security

Before changing anything

Risk
Timeout and plan changes affect every request behind the Tunnel-backed hostname. Raising a timeout masks origin slowness instead of fixing it, and a wrong plan or routing change can break all remote access instead of fixing one upload.[2]
Safer check
Confirm the 524 wording, the read-side versus write-side classification, and the trusted non-Tunnel origin timing, and record the current timeout and plan state before changing anything.[2]
Expected result
After the change, the same upload completes through the Tunnel-backed hostname within the applicable timeout while other endpoints are unaffected.[2]
Backup / recovery access
Record the prior timeout and plan settings so the previous behavior can be restored exactly.[2]
Rollback
Restore the recorded prior settings if the upload does not recover, then re-collect the origin timing before further changes.[2]

When the origin timing evidence provably selects one timeout side, fix the responsible side: reduce origin response time or request-body write duration, or change the applicable plan or configuration where Cloudflare documentation supports it. Only Enterprise zones can raise the proxy read timeout, up to 6000 seconds, and the 30-second proxy write timeout cannot be adjusted. If the evidence cannot distinguish the read side from the write side, collect origin and proxy timing evidence and stop before mutation. Never expose Immich directly to the Internet, disable Tunnel security, open arbitrary ports, disable TLS, bypass authentication, or disable timeouts globally as a generic fix.[2]

Read-only

Hand Tunnel origin evidence to the Tunnel diagnosis

Hand the Tunnel 502 wording, the connected tunnel state, the ingress service URL, and the cloudflared log signature to the Cloudflare Tunnel origin diagnosis. Tunnel ingress, scheme, port, and certificate trust stay with that procedure; no Immich setting substitutes for an unreachable origin.[3]

Potentially disruptive

Correct the responsible hop against the Immich proxy requirements

Before changing anything

Risk
Proxy changes affect every client behind that hop, not only the failing upload. A wrong limit, timeout, header, or TLS change can break all remote access instead of fixing one upload.[5]
Safer check
Confirm the Tunnel-only failure with the same asset, identify the responsible hop, and record its current limits, timeouts, TLS, header, and routing settings before editing.[5]
Expected result
After the correction, the same asset uploads through the Tunnel-backed hostname while trusted non-Tunnel uploads keep working; other proxied services are unaffected.[5]
Backup / recovery access
Preserve the recorded prior proxy settings so the previous hop behavior can be restored exactly.[5]
Rollback
Restore the recorded prior proxy settings if uploads do not recover, then re-collect the Tunnel-only evidence before further changes.[5]

Correct only the proven hop violation: forwarded headers, large-upload allowance with buffering disabled, websocket upgrades, root-path serving, or well-known routing. Treat documented example values as comparison references, never as values to adopt blindly, and retest the same asset through the Tunnel-backed hostname afterwards.[5]

Read-only

If both paths fail, return to the generic Immich upload diagnosis

When the same asset fails over both the trusted non-Tunnel path and the Tunnel-backed hostname, the evidence selects server-side storage, dependency, selection, or background causes. Return to the generic Immich mobile backup diagnosis and preserve all comparison evidence.[4]

Read-only

If no branch is proven: preserve the evidence

Record the exact server and mobile versions, the Cloudflare plan, the asset size, the same-asset comparison on the Tunnel and non-Tunnel paths with synchronized origin and proxy timing logs, the producer attribution evidence, and the exact response wording. Send the sanitized evidence to the operator; an unproven timeout side or an unattributed 413 never justifies a plan, zone, or routing change, reset, reinstall, or security bypass.[4][1][2]

Warnings and boundaries

A Cloudflare-attributed 413 response is a documented edge body-size limit, not an Immich mobile app bug. A bare 413 without Cloudflare attribution is not proof of a plan or zone limit. Never reinstall the app, wipe app data, or reset the mobile database as a response to a size-limit observation.[1][4]
Never expose Immich directly to the Internet, disable Tunnel security, open arbitrary firewall ports, disable TLS verification, disable Cloudflare protection, or bypass authentication as a generic upload test. The non-Tunnel comparison is allowed only through a separately designed path that already exists, is trusted, and is securely configured.[5]
A Tunnel-only failure never proves database corruption, disk failure, or a broken Immich installation. Never wipe app data, delete server database rows, flush Valkey, recreate the database, disable integrity checks, or reinstall as a generic Tunnel-path fix.[4]

Editorial verification

The citations beside technical claims show their evidence. HomeLabFix chooses the diagnostic order and states where the evidence stops supporting a conclusion.

Author and technical editor
Andrey Tretyak
Verification basis
The cited vendor or project documentation plus the page-specific reasoning above.
Hands-on status
Direct reproduction is claimed only when a page explicitly describes the tested environment and result. “Last verified” means the cited evidence was reviewed on that date; it does not mean every procedure was reproduced.
Creation process
Read how HomeLabFix uses source review, human editorial approval, automation, and AI-assisted tools.
Correction path
Report a source change, scope error, or reproducible contradiction.

Sources

Links were reviewed on 2026-09-16. Reachability and automated validation do not replace editorial verification of each claim.

  1. Error 413 (Payload Too Large)
    Cloudflare · Tier A · accessed 2026-09-16
  2. Error 524 (A timeout occurred)
    Cloudflare · Tier A · accessed 2026-09-16
  3. Common errors (Cloudflare Tunnel)
    Cloudflare · Tier A · accessed 2026-09-16
  4. Mobile backup behavior
    Immich project · Tier A · accessed 2026-09-08
  5. Reverse proxy upload limits and routing
    Immich project · Tier A · accessed 2026-09-16

Still troubleshooting?