{"record":{"id":"acd7244887021592","repo":"GoogleContainerTools/jib","slug":"sha-256-algorithm-produced-invalid-hash-ex-getm","errorCode":null,"errorMessage":"SHA-256 algorithm produced invalid hash: + ex.getMessage()","messagePattern":"SHA-256 algorithm produced invalid hash: \\+ ex\\.getMessage\\(\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/hash/CountingDigestOutputStream.java","lineNumber":74,"sourceCode":"   */\n  public BlobDescriptor computeDigest() {\n    try {\n      byte[] hashedBytes = digest.digest();\n\n      // Encodes each hashed byte into 2-character hexadecimal representation.\n      StringBuilder stringBuilder = new StringBuilder(2 * hashedBytes.length);\n      for (byte b : hashedBytes) {\n        stringBuilder.append(String.format(\"%02x\", b));\n      }\n      String hash = stringBuilder.toString();\n\n      BlobDescriptor blobDescriptor =\n          new BlobDescriptor(bytesSoFar, DescriptorDigest.fromHash(hash));\n      bytesSoFar = 0;\n      return blobDescriptor;\n\n    } catch (DigestException ex) {\n      throw new RuntimeException(\"SHA-256 algorithm produced invalid hash: \" + ex.getMessage(), ex);\n    }\n  }\n\n  @Override\n  public void write(byte[] data, int offset, int length) throws IOException {\n    super.write(data, offset, length);\n    bytesSoFar += length;\n  }\n\n  @Override\n  public void write(int singleByte) throws IOException {\n    super.write(singleByte);\n    bytesSoFar++;\n  }\n}\n","sourceCodeStart":56,"sourceCodeEnd":90,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/hash/CountingDigestOutputStream.java#L56-L90","documentation":"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.","triggerScenarios":"Calling computeDigest() (directly or via blobDescriptor()) when MessageDigest.digest() returns a string DescriptorDigest rejects — malformed hex or wrong length from the underlying provider.","commonSituations":"Broken/custom JCE providers, JVM bugs, or bytecode-instrumented digests in exotic environments; essentially never seen on standard JVMs.","solutions":["Run on a standard, up-to-date JVM","Remove custom security providers or java.security modifications","Verify no agent/instrumentation is altering MessageDigest","Update the JDK — this indicates a platform defect"],"exampleFix":"// before\n// custom JCE provider registered globally\nSecurity.insertProviderAt(new CustomProvider(), 1);\n// after\n// use default JVM providers\n// (remove the custom provider registration)","handlingStrategy":"try-catch","validationCode":"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); }","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["Avoid custom JCE providers and JVM agents that instrument crypto","Keep the JDK updated","Run a startup self-test that digests a known vector and compares the hash"],"tags":["jvm","security","sha-256","digest"],"backgroundTag":"broken-jvm-provider","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"}