{"record":{"id":"108780473cee40a0","repo":"GoogleContainerTools/jib","slug":"invalid-digest-digest","errorCode":null,"errorMessage":"Invalid digest: ${digest}","messagePattern":"Invalid digest: (.+?)","errorType":"exception","errorClass":"DigestException","httpStatus":null,"severity":"error","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/api/DescriptorDigest.java","lineNumber":74,"sourceCode":"   */\n  public static DescriptorDigest fromHash(String hash) throws DigestException {\n    if (!hash.matches(HASH_REGEX)) {\n      throw new DigestException(\"Invalid hash: \" + hash);\n    }\n\n    return new DescriptorDigest(hash);\n  }\n\n  /**\n   * Creates a new instance from a valid digest string.\n   *\n   * @param digest the digest to generate the {@link DescriptorDigest} from\n   * @return a new {@link DescriptorDigest} created from the digest\n   * @throws DigestException if the digest is invalid\n   */\n  public static DescriptorDigest fromDigest(String digest) throws DigestException {\n    if (!digest.matches(DIGEST_REGEX)) {\n      throw new DigestException(\"Invalid digest: \" + digest);\n    }\n\n    // Extracts the hash portion of the digest.\n    String hash = digest.substring(DIGEST_PREFIX.length());\n    return new DescriptorDigest(hash);\n  }\n\n  private DescriptorDigest(String hash) {\n    this.hash = hash;\n  }\n\n  public String getHash() {\n    return hash;\n  }\n\n  @Override\n  public String toString() {\n    return DIGEST_PREFIX + hash;","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/api/DescriptorDigest.java#L56-L92","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the digest string matches 'sha256:[a-f0-9]{64}' (or valid algorithm + 64 lowercase hex chars) before passing it","Add the algorithm prefix if you only have the raw hash, e.g. 'sha256:' + hash","Trim whitespace and ensure no truncation occurred when copying the value","Catch DigestException and surface a clear message about the malformed digest"],"exampleFix":"// before\nDescriptorDigest d = DescriptorDigest.fromDigest(hash);\n// after\nString digest = hash.startsWith(\"sha256:\") ? hash : \"sha256:\" + hash;\nDescriptorDigest d = DescriptorDigest.fromDigest(digest);","handlingStrategy":"validation","validationCode":"boolean isValidDigest(String s) { return s != null && s.matches(\"[a-zA-Z0-9]+:[a-f0-9]{64}\"); }","typeGuard":"if (digest == null || !digest.matches(\"[a-zA-Z0-9]+:[a-f0-9]{64}\")) return null; DescriptorDigest d = DescriptorDigest.fromDigest(digest);","tryCatchPattern":"try { DescriptorDigest d = DescriptorDigest.fromDigest(digest); } catch (DigestException e) { log.warn(\"Malformed digest: {}\", e.getMessage()); }","preventionTips":["Validate digests with a regex before calling fromDigest","Keep the algorithm prefix on hashes end-to-end","Trim and normalize digest strings read from external sources"],"tags":["digest","validation","jib"],"backgroundTag":"invalid-argument-format","analyzedSha":"fb949e2676afbbd7dd7a1ef61e20251931325654","analyzedAt":"2026-09-06T14:04:09.491Z","contentChangedAt":"2026-09-06T14:04:09.491Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}