Skip to content

Allow overriding the hard-coded binary cache URL (https://cache.nixos.org) via an environment variable #2993

Open

Description

@jasal82

What problem are you trying to solve?

Summary

Devbox hard-codes https://cache.nixos.org as its binary cache. Nix itself can be pointed at a mirror (substituters in nix.conf), but devbox still contacts cache.nixos.org directly. As a result, devbox can't install packages where only an internal mirror is reachable (air-gapped CI runners, corporate networks), even when the project has a complete devbox.lock and every package is available from the mirror.

Please add an environment variable, for example DEVBOX_BINARY_CACHE, that overrides this URL. That would match how DEVBOX_SEARCH_HOST and DEVBOX_CACHE work today.

Environment

  • Devbox 0.18.4 (official devbox_0.18.4_linux_amd64 release binary); also reproduced with 0.17.2
  • Nix 2.35.2
  • Linux x86_64 (container)
  • nix.conf: substituters = https://artifactory.example.com/artifactory/api/nix/cache.nixos.org-nix-remote (a pull-through mirror of cache.nixos.org)
  • DEVBOX_CACHE=https://artifactory.example.com/artifactory/github.com (a mirror of github.com)

Steps to reproduce

  1. On a machine with internet access, create a project and commit its devbox.json and devbox.lock:
    devbox init && devbox add hello
  2. In an environment where only the mirror is reachable (outbound traffic to cache.nixos.org, github.com etc. is blocked) and Nix's substituters points at the mirror, run:
    devbox install

Actual behavior

Devbox sends HEAD https://cache.nixos.org/<hash>.narinfo. That request fails, so devbox treats the package as not cached and builds it from nixpkgs sources on GitHub:

Info: Installing the following packages to the nix store: hello@latest
unpacking 'github:NixOS/nixpkgs/c27cdad491a991b11ed731760aa2ef8db0cb0410' into the Git cache...
error:
       … while fetching the input 'github:NixOS/nixpkgs/c27cdad491a991b11ed731760aa2ef8db0cb0410'

       error: Failed to open archive (Source threw exception: error: unable to download 'https://github.com/NixOS/nixpkgs/archive/c27cdad491a991b11ed731760aa2ef8db0cb0410.tar.gz': Could not connect to server (7) CONNECT tunnel failed, response 403)
Error: nix: command error: nix ... build --impure --no-link 'github:NixOS/nixpkgs/c27cdad491a991b11ed731760aa2ef8db0cb0410#hello': exit code 1

The locked store path (/nix/store/wzr035k31pmpn2caabq8qwv1npg571z9-hello-2.12.3) is available from the configured substituter. If devbox knew the package was cached, Nix could substitute it directly. This fallback also ignores DEVBOX_CACHE.

In 0.17.2 the failed request was a hard error instead:

Error: Head "https://cache.nixos.org/wzr035k31pmpn2caabq8qwv1npg571z9.narinfo": Filtered

Expected behavior

Devbox either uses a binary cache URL I can configure, or follows Nix's configured substituters, so that installing a locked project needs only the mirror.

Where the URL is hard-coded (v0.18.4)

Location Purpose
internal/devpkg/narinfo_cache.go:19: const binaryCache = "https://cache.nixos.org" HEAD request for <hash>.narinfo to decide whether a package is cached; a miss triggers the GitHub fallback above
internal/shellgen/tmpl/flake.nix.tmpl:51: fromStore = "https://cache.nixos.org"; builtins.fetchClosure in the generated flake

internal/lock/resolve.go:185 (nix.StorePathFromHashPart(ctx, sysInfo.StoreHash, "https://cache.nixos.org")) also hard-codes the URL. It's only used by the /v1/resolve path (DEVBOX_FEATURE_RESOLVE_V2=0), which is not the default.

Related: the stdenv nixpkgs input ignores DEVBOX_CACHE

DEVBOX_CACHE rewrites nixpkgs flake inputs for packages to <DEVBOX_CACHE>/nixos/nixpkgs/archive/<rev>.tar.gz (internal/shellgen/nixpkgs.go). The stdenv input is still written verbatim (nixpkgs.url = "{{ .Stdenv }}"; in flake.nix.tmpl:5), so nix print-dev-env downloads https://github.com/NixOS/nixpkgs/archive/<rev>.tar.gz directly. Applying the same mirror logic to the stdenv input would let a locked project work with only the mirror reachable. I can open this as a separate issue if you prefer.

What solution would you like?

Proposal

  • Add DEVBOX_BINARY_CACHE (the name is only a suggestion). It defaults to https://cache.nixos.org and is used in all places above.
  • Alternative: read the first HTTP(S) entry of Nix's substituters setting (nix config show substituters), falling back to https://cache.nixos.org.

Alternatives you've considered

Workaround

We currently patch the source at build time: substituteInPlace swaps https://cache.nixos.org for our mirror URL, and the stdenv template line is changed to use the mirror. With both patches, devbox install, devbox run and devbox shell work for locked projects with only the mirror reachable. We'd like to drop this patch.

Activity

  1. anunayasri commented on Oct 27, 2026

    @anunayasri

    Hey @mikeland73 . I would love to give this one a try. Could you assign it to me.

  2. anunayasri commented on Oct 28, 2026

    @anunayasri

    Hey Team. I want to get consensus on implementation strategy before writing(and testing) the fix.

    I understand that cache.nixos.org is used in two places. Both needs to point to the new mirror url.

    1. Devbox uses it to probe the cache - internal/devpkg/narinfo_cache.go > fetchNarInfoStatusFromHTTP(ctx, binaryCache, hash)
    2. Nix uses it to download the packages - internal/nix/build.go > Build(). Note that the cache url is not an arg here.

    Config needs to specified in two places -

    1. Env var DEVBOX_NIX_CACHE_URL
      • For the devbox's probing logic.
      • It will be passed to nix build cmd (internal/nix/build.go > Build()) using --option substituters
    2. Specifying a mirror url is insufficient. Nix must also trust the server. This needs to be specified in nix.conf file.
      extra-substituters = https://nix-mirror.example
      extra-trusted-public-keys = nix-mirror.example-1:REPLACE_WITH_MIRROR_PUBLIC_KEY

    Separation of concerns: The fix is not responsible for updating nix.conf. Devbox and nix configs must not be coupled. Users might use devbox with an existing nix installation.

    Out of scope: Support for multiple cache servers.

    🛟 I haven't used nix before. Would appreciate if someone can guide me - How to test end to end after the fix—including a reachable mirror, any required authentication, substituter authorization, and signing keys.

    cc: @mikeland73, if you have context or could route the query to the relevant eng.

  3. mikeland73 commented on Nov 2, 2026

    @mikeland73
    Collaborator

    Thanks for writing this up! A couple of adjustments:

    • No need for --option substituters on nix build. When a package is cached, devbox builds the store path directly, and Nix already uses the substituters and trusted-public-keys from nix.conf. Overriding substituters from the client is also ignored for non-trusted users on multi-user installs.
    • Rather than a new env var, let's read the cache URL from Nix's config: the first http(s) entry of substituters via nix.CurrentConfig() (internal/nix/config.go), falling back to https://cache.nixos.org. Then users configure the mirror once, in nix.conf.
    • Use that URL everywhere cache.nixos.org is hardcoded: the narinfo probe (internal/devpkg/narinfo_cache.go), fromStore in internal/shellgen/tmpl/flake.nix.tmpl and internal/shellgen/flake_plan.go, and internal/lock/resolve.go. fetchClosure downloads <fromStore>/nix-cache-info even when the path is already local, so it has to be reachable.

    To test without a real mirror: set substituters = https://nix-community.cachix.org (any reachable cache other than cache.nixos.org) and block cache.nixos.org, for example with an /etc/hosts entry. devbox install and devbox shell on a locked project should then send no requests to cache.nixos.org (check with DEVBOX_DEBUG=1).


    Written by Claude on behalf of / prompted by @mikeland73.

  4. logan-egbert commented on Nov 13, 2026

    @logan-egbert

    I'm getting the Error: Head "https://cache.nixos.org/zslkhz79mpnk945p5xhrixqch693b0k1.narinfo": context deadline exceeded when trying to update my packages globally. Is this fix related to that issue @anunayasri ?

  5. anunayasri commented on Nov 14, 2026

    @anunayasri

    I'm getting the Error: Head "https://cache.nixos.org/zslkhz79mpnk945p5xhrixqch693b0k1.narinfo": context deadline exceeded when trying to update my packages globally. Is this fix related to that issue @anunayasri ?

    Hey @logan-egbert . If you are working behind a firewall that blocks cache.nixos.org or your company uses a nix cache mirror, then yes.

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

Metadata

Metadata

Assignees

Labels

featureNew feature or requesttriageIssue needs triage

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions