{"record":{"id":"bf43d19f83aafdd4","repo":"golang/go","slug":"crypto-rsa-requested-hash-function-unavailable","errorCode":null,"errorMessage":"crypto/rsa: requested hash function unavailable: ","messagePattern":"crypto/rsa: requested hash function unavailable: ","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/fips.go","lineNumber":86,"sourceCode":"\t}\n\n\tif opts != nil && opts.Hash != 0 {\n\t\thash = opts.Hash\n\t}\n\n\tif boring.Enabled && rand.IsDefaultReader(random) && priv.N.BitLen() >= 1024 {\n\t\tbkey, err := boringPrivateKey(priv)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn boring.SignRSAPSS(bkey, hash, digest, opts.saltLength())\n\t}\n\tif priv.N.BitLen() >= 1024 {\n\t\tboring.UnreachableExceptTests()\n\t}\n\n\tif !hash.Available() {\n\t\treturn nil, errors.New(\"crypto/rsa: requested hash function unavailable: \" + hash.String())\n\t}\n\th := fips140hash.Unwrap(hash.New())\n\n\tif err := checkFIPS140OnlyPrivateKey(priv); err != nil {\n\t\treturn nil, err\n\t}\n\tif fips140only.Enforced() && !fips140only.ApprovedHash(h) {\n\t\treturn nil, errors.New(\"crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode\")\n\t}\n\tif fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) {\n\t\treturn nil, errors.New(\"crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode\")\n\t}\n\n\tk, err := fipsPrivateKey(priv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/fips.go#L68-L104","documentation":"Returned inside RSA PSS signing when the requested hash is not available — hash.Available() returns false. This happens when the hash package's constructor is not linked into the binary (e.g., the hash is in a package not imported anywhere) so hash.New would panic. The guard prevents that panic with an explicit, descriptive error naming the hash.","triggerScenarios":"Referencing a crypto.Hash constant (e.g., crypto.SHA512) whose implementing package is not imported anywhere in the build, causing hash.Available() to be false. Using a hash identifier the linker dead-stripped.","commonSituations":"Binary-stripped builds where only some hash implementations are retained. Code paths that select a hash via a constant without importing the hash package. Cross-compiling with reduced crypto subsets.","solutions":["Ensure the hash implementation is imported: add a blank import like _ \"crypto/sha512\" if needed.","Confirm hash.Available() is true before signing.","Switch to a hash whose package is already imported in the build."],"exampleFix":"// before\nimport \"crypto/rsa\"\n// sha512 package never imported -> hash.Available() false\nsig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA512, digest, opts)\n\n// after\nimport (\n  \"crypto/rsa\"\n  _ \"crypto/sha512\"\n)\nsig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA512, digest, opts)","handlingStrategy":"validation","validationCode":"if !hash.Available() {\n    return nil, fmt.Errorf(\"hash %s not linked into binary\", hash)\n}\nreturn rsa.SignPSS(rand.Reader, priv, hash, digest, opts)","typeGuard":"func hashLinked(h crypto.Hash) bool { return h.Available() }","tryCatchPattern":"sig, err := rsa.SignPSS(rand.Reader, priv, hash, digest, opts)\nif err != nil && strings.Contains(err.Error(), \"hash function unavailable\") {\n    // import the hash package or switch to crypto.SHA256\n}\nreturn sig, err","preventionTips":["Import hash packages explicitly (even as blank imports) in packages that reference their crypto.Hash constants.","Check hash.Available() before signing in dynamically-configured code.","Verify the binary retains the hash implementation after linking/stripping."],"tags":["cryptography","go","rsa","pss","hash-function","linker"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}