GoogleContainerTools/jib · critical · RuntimeException

SHA-256 algorithm produced invalid hash: + ex.getMessage()

Error message

SHA-256 algorithm produced invalid hash: + ex.getMessage()

What it means

computeDigest finishes the SHA-256 digest and converts the hex hash into a DescriptorDigest; a DigestException there means the digest string was not valid SHA-256 output. The library wraps it in this RuntimeException because a correct SHA-256 implementation can never produce an invalid hash — this indicates a JVM/algorithm defect or corrupted digest state.

Source

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

   */
  public BlobDescriptor computeDigest() {
    try {
      byte[] hashedBytes = digest.digest();

      // Encodes each hashed byte into 2-character hexadecimal representation.
      StringBuilder stringBuilder = new StringBuilder(2 * hashedBytes.length);
      for (byte b : hashedBytes) {
        stringBuilder.append(String.format("%02x", b));
      }
      String hash = stringBuilder.toString();

      BlobDescriptor blobDescriptor =
          new BlobDescriptor(bytesSoFar, DescriptorDigest.fromHash(hash));
      bytesSoFar = 0;
      return blobDescriptor;

    } catch (DigestException ex) {
      throw new RuntimeException("SHA-256 algorithm produced invalid hash: " + ex.getMessage(), ex);
    }
  }

  @Override
  public void write(byte[] data, int offset, int length) throws IOException {
    super.write(data, offset, length);
    bytesSoFar += length;
  }

  @Override
  public void write(int singleByte) throws IOException {
    super.write(singleByte);
    bytesSoFar++;
  }
}

View on GitHub (pinned to fb949e2676)

Solutions

  1. Run on a standard, up-to-date JVM
  2. Remove custom security providers or java.security modifications
  3. Verify no agent/instrumentation is altering MessageDigest
  4. Update the JDK — this indicates a platform defect

Example fix

// before
// custom JCE provider registered globally
Security.insertProviderAt(new CustomProvider(), 1);
// after
// use default JVM providers
// (remove the custom provider registration)
Defensive patterns

Strategy: try-catch

Validate before calling

try { byte[] d = java.security.MessageDigest.getInstance("SHA-256").digest(new byte[0]); assert d.length == 32; } catch (Exception e) { throw new IllegalStateException("Broken SHA-256 provider", e); }

Try / catch

try { jibStep(); } catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().contains("produced invalid hash")) { failBuild("JVM digest provider is defective; update JDK"); } throw e; }

Prevention

When it happens

Trigger: Calling computeDigest() (directly or via blobDescriptor()) when MessageDigest.digest() returns a string DescriptorDigest rejects — malformed hex or wrong length from the underlying provider.

Common situations: Broken/custom JCE providers, JVM bugs, or bytecode-instrumented digests in exotic environments; essentially never seen on standard JVMs.

Related errors


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