Skip to content

Conversation

@xingyaoww
Copy link
Collaborator

@xingyaoww xingyaoww commented Nov 4, 2025

Problem

Docker image tags have a maximum length of 128 characters. When building with long base image names (e.g., SWE-Bench images like docker.io/s/swebench/s/sweb.eval.x86_64.scikit-learn__scikit-learn-25973:latest), the generated cache tags can exceed this limit and cause build failures with:

ERROR: failed to solve: failed to configure registry cache exporter: invalid reference format

This issue occurs when the base_image_slug (created from the base image name with / and : replaced by _s_) combined with the cache prefix (buildcache-{target}-) and branch name suffix exceeds 128 characters.

Example of a tag that exceeds the limit:

buildcache-source-minimal-docker.io_s_swebench_s_sweb.eval.x86_64.scikit-learn__scikit-learn-25973_tag_latest-refs-pull-51-merge

This tag is 133 characters long, exceeding Docker's 128-character limit by 5 characters.

Solution

This PR implements a fix that hashes the base_image_slug when it would cause the final cache tag to exceed 128 characters. It uses SHA256 hash (first 12 chars) to create a shorter unique identifier while maintaining cache efficiency across builds.

Changes:

  • Imports hashlib for SHA256 hashing
  • Calculates the maximum available space for base_slug given the prefix and branch suffix
  • If the base_slug would cause overflow, replaces it with a 12-char hash
  • Preserves the original slug for shorter image names (no impact on common use cases)
  • Adds debug logging when hashing is applied

Example with the fix:

For the same scikit-learn image, the new cache tag would be:

buildcache-source-minimal-8a1b2c3d4e5f-refs-pull-51-merge

This is well under the 128-character limit while maintaining uniqueness.

Testing

This fix has been tested in the OpenHands/benchmarks repository PR OpenHands/benchmarks#51, where it successfully resolves the build failures for SWE-Bench images with long names.

Impact

  • ✅ No impact on existing cache tags for common use cases (short image names)
  • ✅ Enables building images with arbitrarily long base image names
  • ✅ Maintains cache effectiveness through consistent hashing
  • ✅ Backward compatible - only affects tags that would have failed previously

Related Issues

This fix is being used in OpenHands/benchmarks#51 to enable building SWE-Bench Docker images.

@xingyaoww can click here to continue refining the PR


Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.12-nodejs22 Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:336db96-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-336db96-python \
  ghcr.io/openhands/agent-server:336db96-python

All tags pushed for this build

ghcr.io/openhands/agent-server:336db96-golang-amd64
ghcr.io/openhands/agent-server:v1.0.0a5_golang_tag_1.21-bookworm_binary-amd64
ghcr.io/openhands/agent-server:336db96-golang-arm64
ghcr.io/openhands/agent-server:v1.0.0a5_golang_tag_1.21-bookworm_binary-arm64
ghcr.io/openhands/agent-server:336db96-java-amd64
ghcr.io/openhands/agent-server:v1.0.0a5_eclipse-temurin_tag_17-jdk_binary-amd64
ghcr.io/openhands/agent-server:336db96-java-arm64
ghcr.io/openhands/agent-server:v1.0.0a5_eclipse-temurin_tag_17-jdk_binary-arm64
ghcr.io/openhands/agent-server:336db96-python-amd64
ghcr.io/openhands/agent-server:v1.0.0a5_nikolaik_s_python-nodejs_tag_python3.12-nodejs22_binary-amd64
ghcr.io/openhands/agent-server:336db96-python-arm64
ghcr.io/openhands/agent-server:v1.0.0a5_nikolaik_s_python-nodejs_tag_python3.12-nodejs22_binary-arm64
ghcr.io/openhands/agent-server:336db96-golang
ghcr.io/openhands/agent-server:336db96-java
ghcr.io/openhands/agent-server:336db96-python

About Multi-Architecture Support

  • Each variant tag (e.g., 336db96-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., 336db96-python-amd64) are also available if needed

Docker image tags have a maximum length of 128 characters. When building
with long base image names (e.g., SWE-Bench images like scikit-learn), the
generated cache tags can exceed this limit and cause build failures with:
'ERROR: failed to configure registry cache exporter: invalid reference format'

This issue occurs when the base_image_slug (created from the base image name
with / and : replaced) combined with the cache prefix and branch name exceeds
128 characters.

Solution: Hash the base_image_slug when it would cause the final cache tag
to exceed 128 characters. Uses SHA256 hash (first 12 chars) to create a
shorter unique identifier while maintaining cache efficiency across builds.

The fix:
- Imports hashlib for SHA256 hashing
- Calculates the maximum available space for base_slug given the prefix and
  branch suffix
- If the base_slug would cause overflow, replaces it with a 12-char hash
- Preserves the original slug for shorter image names (no impact on common
  use cases)

This maintains cache effectiveness while supporting arbitrarily long base
image names.

Co-authored-by: openhands <[email protected]>
@xingyaoww xingyaoww force-pushed the fix/docker-cache-tag-length-limit branch from fecf4ac to 9632dbb Compare November 4, 2025 21:57
@enyst
Copy link
Collaborator

enyst commented Nov 5, 2025

@OpenHands Do a /codereview-roasted on this PR. When you answer, make sure to use github markdown, you know, some bold or something for readability.

@openhands-ai
Copy link

openhands-ai bot commented Nov 5, 2025

I'm on it! enyst can track my progress at all-hands.dev

@openhands-ai
Copy link

openhands-ai bot commented Nov 5, 2025

Here’s a concise summary of my /codereview-roasted on PR #1029 (Fix Docker cache tag length exceeding 128 characters):

  • Overall: The fix addresses a real build failure and is mostly simple and pragmatic. Rating: Acceptable.
  • Critical issues identified:
    • versioned_tag still uses the full base_image_slug and can exceed Docker’s 128-char limit. Apply the same shortening strategy used for cache tags.
    • The length calculation doesn’t account for the unconditional “-main” warm-cache reference when not on main, so cache_tag_base + “-main” can still overflow.
    • Comment/code mismatch: comment says “first 8 chars,” code uses 12.
  • Improvement suggestions:
    • Centralize the tag-shortening logic in a helper and reuse for both cache_tags and versioned_tag.
    • Consider a balanced approach to readability: keep a small slice of the slug plus a hash when space allows.
    • Hoist MAX_TAG_LENGTH to a module-level constant.
    • Defensively handle cases where reserved >= MAX_TAG_LENGTH (force hash).
    • Enhance debug logs to include available length/context.
  • Verdict: Needs small rework; core approach is sound, but tighten consistency across all tags and fix the “-main” accounting and comment mismatch.

No code changes were made or pushed; I only provided the review feedback as requested.

View full conversation

@xingyaoww xingyaoww merged commit 703718d into main Nov 5, 2025
20 checks passed
@xingyaoww xingyaoww deleted the fix/docker-cache-tag-length-limit branch November 5, 2025 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants