{"record":{"id":"2e507eed61a54cc6","repo":"gofiber/fiber","slug":"decode-sha256-password-w","errorCode":null,"errorMessage":"decode SHA256 password: %w","messagePattern":"decode SHA256 password: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/basicauth/config.go","lineNumber":288,"sourceCode":"\tcase strings.HasPrefix(h, \"{SHA512}\"):\n\t\tb, err := base64.StdEncoding.DecodeString(h[len(\"{SHA512}\"):])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"decode SHA512 password: %w\", err)\n\t\t}\n\t\t// A digest of the wrong size can never equal a SHA-512 sum, so\n\t\t// accepting it would silently reject every password for this user.\n\t\t// Report it instead, which surfaces as a panic at startup.\n\t\tif len(b) != sha512.Size {\n\t\t\treturn nil, ErrInvalidSHA512PasswordLength\n\t\t}\n\t\treturn func(p string) bool {\n\t\t\tsum := sha512.Sum512([]byte(p))\n\t\t\treturn subtle.ConstantTimeCompare(sum[:], b) == 1\n\t\t}, nil\n\tcase strings.HasPrefix(h, \"{SHA256}\"):\n\t\tb, err := base64.StdEncoding.DecodeString(h[len(\"{SHA256}\"):])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"decode SHA256 password: %w\", err)\n\t\t}\n\t\tif len(b) != sha256.Size {\n\t\t\treturn nil, ErrInvalidSHA256PasswordLength\n\t\t}\n\t\treturn func(p string) bool {\n\t\t\tsum := sha256.Sum256([]byte(p))\n\t\t\treturn subtle.ConstantTimeCompare(sum[:], b) == 1\n\t\t}, nil\n\tdefault:\n\t\tb, err := hex.DecodeString(h)\n\t\tif err != nil || len(b) != sha256.Size {\n\t\t\tif b, err = base64.StdEncoding.DecodeString(h); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"decode SHA256 password: %w\", err)\n\t\t\t}\n\t\t\tif len(b) != sha256.Size {\n\t\t\t\treturn nil, ErrInvalidSHA256PasswordLength\n\t\t\t}\n\t\t}","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/basicauth/config.go#L270-L306","documentation":"Returned by parseHashedPassword when a '{SHA256}'-prefixed password string cannot be base64-decoded. Same shape as the SHA512 case but for the 32-byte SHA-256 digest path. The {SHA256} prefix is what Apache's htpasswd emits for SHA-256, so mis-serialized htpasswd entries are the most common cause.","triggerScenarios":"Users map value is '{SHA256}<not-base64>': bad characters, URL-safe alphabet, missing padding, or trailing newline. Frequently seen when migrating entries from Apache htpasswd that were re-encoded or truncated.","commonSituations":"htpasswd -s output pasted with a trailing newline; secret manager base64'd the already-base64 value; encoding alphabet mismatch (URL-safe vs standard); YAML loader that interpreted '+/=' as special.","solutions":["Regenerate with standard base64 of the raw 32-byte SHA-256 digest.","Verify with htpasswd -vb that the entry is well-formed before pasting.","Strip whitespace and confirm exactly one '='-padded token follows {SHA256}.","Ensure the decoded length is 32 bytes (sha256.Size) to avoid the next guard's ErrInvalidSHA256PasswordLength.","Quote the value in YAML/JSON to prevent '+/=' interpretation."],"exampleFix":"// before\n\"{SHA256}\" + strings.ReplaceAll(stdB64, \"+\", \"-\") // accidentally URL-safe\n\n// after\n\"{SHA256}\" + base64.StdEncoding.EncodeToString(sum[:])","handlingStrategy":"validation","validationCode":"func validateSHA256Hash(h string) error {\n    if !strings.HasPrefix(h, \"{SHA256}\") { return nil }\n    b, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(h, \"{SHA256}\"))\n    if err != nil { return fmt.Errorf(\"bad SHA256 base64: %w\", err) }\n    if len(b) != sha256.Size { return fmt.Errorf(\"SHA256 digest must be %d bytes, got %d\", sha256.Size, len(b)) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate digests with standard base64 of the raw 32-byte SHA-256 sum.","Verify htpasswd -s entries before pasting into config.","Quote credential strings in YAML to protect '+/=' characters.","Run an init-time validator over the Users map."],"tags":["basicauth","authentication","password-hash","base64","config","sha256"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}