GoogleContainerTools/jib · error · DigestException

Invalid digest: ${digest}

Error message

Invalid digest: ${digest}

What it means

DescriptorDigest.fromDigest validates that a digest string matches the OCI/docker digest format (algorithm:hex hash, e.g. sha256:...). If the string does not match DIGEST_REGEX, it throws DigestException with the offending value. This guards against malformed digests being used as image references or layer identifiers.

Source

Thrown at jib-core/src/main/java/com/google/cloud/tools/jib/api/DescriptorDigest.java:74

   */
  public static DescriptorDigest fromHash(String hash) throws DigestException {
    if (!hash.matches(HASH_REGEX)) {
      throw new DigestException("Invalid hash: " + hash);
    }

    return new DescriptorDigest(hash);
  }

  /**
   * Creates a new instance from a valid digest string.
   *
   * @param digest the digest to generate the {@link DescriptorDigest} from
   * @return a new {@link DescriptorDigest} created from the digest
   * @throws DigestException if the digest is invalid
   */
  public static DescriptorDigest fromDigest(String digest) throws DigestException {
    if (!digest.matches(DIGEST_REGEX)) {
      throw new DigestException("Invalid digest: " + digest);
    }

    // Extracts the hash portion of the digest.
    String hash = digest.substring(DIGEST_PREFIX.length());
    return new DescriptorDigest(hash);
  }

  private DescriptorDigest(String hash) {
    this.hash = hash;
  }

  public String getHash() {
    return hash;
  }

  @Override
  public String toString() {
    return DIGEST_PREFIX + hash;

View on GitHub (pinned to fb949e2676)

Solutions

  1. Verify the digest string matches 'sha256:[a-f0-9]{64}' (or valid algorithm + 64 lowercase hex chars) before passing it
  2. Add the algorithm prefix if you only have the raw hash, e.g. 'sha256:' + hash
  3. Trim whitespace and ensure no truncation occurred when copying the value
  4. Catch DigestException and surface a clear message about the malformed digest

Example fix

// before
DescriptorDigest d = DescriptorDigest.fromDigest(hash);
// after
String digest = hash.startsWith("sha256:") ? hash : "sha256:" + hash;
DescriptorDigest d = DescriptorDigest.fromDigest(digest);
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidDigest(String s) { return s != null && s.matches("[a-zA-Z0-9]+:[a-f0-9]{64}"); }

Type guard

if (digest == null || !digest.matches("[a-zA-Z0-9]+:[a-f0-9]{64}")) return null; DescriptorDigest d = DescriptorDigest.fromDigest(digest);

Try / catch

try { DescriptorDigest d = DescriptorDigest.fromDigest(digest); } catch (DigestException e) { log.warn("Malformed digest: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling DescriptorDigest.fromDigest with a string that is not 'algo:64-hex-chars' — e.g. a bare hash without the 'sha256:' prefix, a truncated hash, uppercase hex, or an unsupported algorithm.

Common situations: Parsing digests from registry API responses or user-supplied config where the value was truncated or lacks the algorithm prefix; hand-editing image digests; copy-pasting a hash from build logs without the prefix.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06). Data as JSON: /api/errors/108780473cee40a0. Report an issue: GitHub.