Skip to content

oci:// mirrors can't be used with registries that have no Docker token endpoint (Amazon ECR) #2624

Description

@earlybard

Checklist

  • I added a descriptive title
  • I searched open reports and couldn't find a duplicate

What happened?

rattler version: rattler_networking on main @ e4ed482, reproduced through pixi 0.72.2

I'm trying to point pixi at an Amazon ECR pull-through cache of ghcr.io/channel-mirrors/conda-forge, so conda packages can be managed via a pull-through cache we already use for container images:

[mirrors]
"https://conda.anaconda.org/conda-forge" = [
  "oci://<acct>.dkr.ecr.<region>.amazonaws.com/cache/ghcr/channel-mirrors/conda-forge",
]

Two things in crates/rattler_networking/src/oci_middleware.rs rule this out.

1. The token exchange is unconditional, and ECR has no token endpoint.
get_blob_url always fetches https://{host}/token?scope=… and fails hard on error. ECR
doesn't serve /token, and its challenge is Basic only:

$ curl -sI https://<acct>.dkr.ecr.<region>.amazonaws.com/v2/ | grep -i www-authenticate
Www-Authenticate: Basic realm="https://<acct>.dkr.ecr.<region>.amazonaws.com/",service="ecr.amazonaws.com"

Credentials don't help, because OciMiddleware never reads the authentication storage — a
RATTLER_AUTH_FILE entry for the registry host is ignored:

$ RATTLER_AUTH_FILE=ecr-auth.json pixi install
Error:   × failed to solve requirements of environment 'default' for platform 'linux-64'
  ├─▶   × Reqwest error: HTTP status client error (401 Unauthorized) for url
  │     │ (https://<acct>.dkr.ecr.<region>.amazonaws.com/token?scope=repository:
  │     │ cache/ghcr/channel-mirrors/conda-forge/noarch/repodata.json:pull)

2. The digest shortcut never triggers the cache import.
When repodata supplies the sha256 (X-Expected-Sha256), get_blob_url addresses the blob directly and skips the manifest. An ECR pull-through cache imports an upstream artifact only when its manifest is pulled, so the first request for every package is a 404 NAME_UNKNOWN, and nothing ever triggers the import that would fix it. An ordinary OCI client can't hit this — it has to read the manifest to learn a digest at all; rattler is unusual in knowing it up front.

The registry side is fine once both are worked around by hand: ECR accepts the conda media types, a manifest pull imports the artifact, and the blob then serves the .conda
byte-for-byte, sha256 matching pixi.lock.

Proposed fix

I have a working patch confined to oci_middleware.rs and would like to open a PR - but there are some design de

  1. Resolve credentials for the registry host from AuthenticationStorage and skip the token exchange when they exist. Registries without stored credentials keep the anonymous path, and new keeps its signature, so nothing changes downstream. A fuller fix would follow the registry's WWW-Authenticate challenge instead of assuming /token — happy to go either way.
  2. When a digest-addressed blob comes back 404, resolve through the manifest and retry once. Costs one extra round trip only on a miss. This is the design call I'd like an opinion on before a PR.
  3. Report a non-2xx manifest response as a 404 for the artifact instead of a serde error from deserializing the error body (previously raised in Missing error check for failed HTTP responses in OCI middleware manifest fetch #2280; still the behaviour on main).

AI Disclosure

This issue report was generated with AI and edited by me.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions