GoogleContainerTools/jib · error · DigestException

Invalid hash: ${hash}

Error message

Invalid hash: ${hash}

What it means

DescriptorDigest.fromHash validates that a hash string is exactly a 64-character lowercase hex SHA-256 digest. Non-conforming strings throw DigestException. This guards digest integrity for layer/image descriptors.

Source

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

  /** The algorithm prefix for the digest string. */
  private static final String DIGEST_PREFIX = "sha256:";

  /** Pattern matches a SHA-256 digest - a SHA-256 hash prefixed with "sha256:". */
  static final String DIGEST_REGEX = DIGEST_PREFIX + HASH_REGEX;

  private final String hash;

  /**
   * Creates a new instance from a valid hash string.
   *
   * @param hash the hash to generate the {@link DescriptorDigest} from
   * @return a new {@link DescriptorDigest} created from the hash
   * @throws DigestException if the hash is invalid
   */
  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.

View on GitHub (pinned to fb949e2676)

Solutions

  1. Strip the "sha256:" prefix before calling fromHash (use fromDigest for prefixed strings if available)
  2. Trim whitespace and ensure the hash is exactly 64 lowercase hex characters
  3. Check the source of the hash — a corrupted/truncated value must be re-fetched from the registry

Example fix

// before
DescriptorDigest d = DescriptorDigest.fromHash(digestString); // "sha256:abc..."
// after
DescriptorDigest d = digestString.contains(":")
    ? DescriptorDigest.fromDigest(digestString)
    : DescriptorDigest.fromHash(digestString);
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidSha256(String s) { return s != null && s.matches("[0-9a-f]{64}"); }

Type guard

DescriptorDigest safeFromHash(String s) throws DigestException { return (s != null && s.matches("[0-9a-f]{64}")) ? DescriptorDigest.fromHash(s) : DescriptorDigest.fromDigest(s); }

Try / catch

try { digest = DescriptorDigest.fromHash(hash); } catch (DigestException e) { digest = DescriptorDigest.fromDigest(normalize(hash)); }

Prevention

When it happens

Trigger: Calling DescriptorDigest.fromHash with a string failing HASH_REGEX — wrong length, uppercase hex, non-hex characters, or a digest string containing an algorithm prefix like "sha256:abc...".

Common situations: Parsing registry API responses where the digest includes the "sha256:" prefix; reading digests from logs/files with whitespace or formatting; truncating or hand-editing digests in tests.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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