Skip to content

EAS_GRADLE_CACHE: cleanup never removes entries, so saves permanently fail once the archive exceeds ~2 GiB #3937

Description

@rencevio

Build/Submit details page URL

https://expo.dev/accounts/asula/projects/dawn-xyz/builds/10d1908e-424c-45ce-a460-ab7d8b97435d

Summary

With EAS_GRADLE_CACHE=1, the build cache enters a permanent failure loop on active projects:

  1. The cleanup configured by your init script does nothing — its own log proves it: [EAS] Gradle build cache entries before cleanup: 5199after build: 5337 (was 5199), growth on every build, never a removal (retention likely can't fire because extraction resets entry timestamps).
  2. Once the archive crosses ~2 GiB, the storage PUT in uploadCacheAsync is rejected — Error: Unexpected response from cache server (400): Bad Request — on every build:
Gradle cache archive size: 2.2 GB
Uploading cache...
Failed to save Gradle cache
  1. The exact key is therefore never written, so every restore is a prefix match of the same stale oversized archive — the loop never self-heals, even across lockfile changes.
  2. All of this is silent: builds succeed and the 400 is only visible in the structured log's err field.

Likely related: the ccache prune before save (ccache --evict-older-than <now - ctx.startTime>s) evicts objects written during the build — a 30-min build with ~17k ccache writes saved a 10.8 MB archive, and the next build restored a cache with 16 files / 0.0 GiB. So neither cache layer persists, and all C++ recompiles every build.

Suggested: validate size at session creation (or raise the cap), log the PUT response body, surface save failures in the UI, and make retention work on ephemeral workers.

Managed or bare?

Managed (CNG/prebuild)

Environment

Server-side EAS Build issue — image ubuntu-26.04-jdk-17-ndk-r27b, resource class medium, SDK 56 / RN 0.85, pnpm, ~13 CMake native modules. Local env not relevant.

Error output

No response

Reproducible demo or steps to reproduce from a blank project

Time/scale-dependent, not reproducible from a blank project — but observable on any project: enable EAS_GRADLE_CACHE=1, run two builds, and watch the init-script entry counts only increase regardless of the 3-day retention. Once accumulated past ~2 GiB (weeks, for a project with many native modules and several profiles sharing the lockfile-hash key), every save 400s. Example builds from 2026-07-02: 10d1908e-424c-45ce-a460-ab7d8b97435d (production), 0a01138e-6bea-4141-8dc9-3dc74e6c8880 (staging). Full logs available on request.

Main cuts: the impact section, the restore/error log blocks (kept one-line quotes inline), four of the six suggested fixes, the env-info dump (replaced with the one line that matters — it's a server-side bug), and the ccache detail compressed to one paragraph. If they push back on the missing expo-env-info output, it takes 10 seconds to paste in from my previous message.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs reviewIssue is ready to be reviewed by a maintainer

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions